Question

Comment puis-je faire le? Feu genOut / String

module IOStream where

import System.IO
import System.IO.Unsafe

class Out a where
  out :: a → String

instance Show a ⇒ Out a where
  out = show

outString :: String → String
outString = id
{-# RULES "genOut/String" out = outString #-}

infixl 9 <<, ≪
(≪), (<<) :: Out a ⇒ IO Handle → a → IO Handle
(<<)= (≪)
h ≪ a = do
  s ← h
  hPutStr s $ out a
  return s

cout, cin, cerr :: IO Handle
cout = return stdout
cin  = return stdin
cerr = return stderr

endl :: String
endl = "\n"

--infixr 9 ∘ °
(∘) = (.)
(°) = flip (∘)

module Main where

import System.IO
import IOStream

foreign import ccall "pi.h f_" f_ :: IO Double

main :: IO Int
main = do
  --putStrLn . show =<< f_

--  ((≪ endl) . (cout ≪)) =<< f_ 
  (cout ≪) ° (≪ endl) =<< f_
  return 0

Compile et lien:

cetin@unique:~/lab/c/linking/demo$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.10.2
cetin@unique:~/lab/c/linking/demo$ ghc -fglasgow-exts -O2 -ddump-simpl-stats -XUndecidableInstances -O2 iostream.hs main.hs pi_v2.o -o hsex2

==================== FloatOut stats: ====================
0 Lets floated to top level; 1 Lets floated elsewhere; from 3 Lambda groups



==================== FloatOut stats: ====================
0 Lets floated to top level; 0 Lets floated elsewhere; from 5 Lambda groups



==================== Grand total simplifier statistics ====================
Total ticks:     184

40 PreInlineUnconditionally
45 PostInlineUnconditionally
24 UnfoldingDone
8 LetFloatFromLet
4 EtaReduction
57 BetaReduction
6 KnownBranch
11 SimplifierDone



==================== FloatOut stats: ====================
0 Lets floated to top level; 0 Lets floated elsewhere; from 1 Lambda groups



==================== FloatOut stats: ====================
3 Lets floated to top level; 0 Lets floated elsewhere; from 1 Lambda groups



==================== Grand total simplifier statistics ====================
Total ticks:     218

42 PreInlineUnconditionally
57 PostInlineUnconditionally
33 UnfoldingDone
9 LetFloatFromLet
1 EtaReduction
66 BetaReduction
10 KnownBranch
12 SimplifierDone

Résultat:

cetin@unique:~/lab/c/linking/demo$ ./hsex2
3.141592653589793"\n"cetin@unique:~/lab/c/linking/demo$ 

attendu:

cetin@unique:~/lab/c/linking/demo$ ./hsex2
3.141592653589793
cetin@unique:~/lab/c/linking/demo$ 

Comment puis-je faire que le feu de la règle?

Était-ce utile?

La solution

On dirait que vous voulez instances se chevauchent , comme vous voulez d'avoir un instance Out String qui est différent de celui qui chevauche instance Show a => Out a il.

{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
{-# LANGUAGE OverlappingInstances, UndecidableInstances #-}
class Out a where out :: a -> String
instance Out String where out = id
instance (Show a) => Out a where out = show

La recommandation générale est d'éviter l'utilisation d'instances se chevauchent et les instances indécidables à moins que vraiment nécessaires, les changements à la vérification du type qu'ils font ne sont pas portables et peuvent causer d'autres problèmes.


Modifier

La mise en œuvre sage, pensez à dictionnaire pour chaque instance d'une classe. << sera donné le dictionnaire pour l'instance de Out qu'il est prévu d'utiliser comme paramètre caché. Depuis out est regardé à partir de là, il n'y a pas de place pour votre RULE au feu. Si out n'étaient pas dans une classe de types, et était appelé à partir d'une fonction non polymorphes, je me attends RULE de match, mais tel qu'il est, ce n'est pas surprenant que cela ne fonctionne pas.

RULE / SPECIALIZE sont censés être des optimisations seulement, et votre code ne devrait pas changer de comportement si elles font ou ne font feu.

Il m'a fallu un certain temps pour réaliser ce que vous faisiez ... vous vous rendez compte que Haskell n'est pas C ++, non? La manière dont le polymorphisme est utilisé est tout à fait différent.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top