Domanda

Come posso fare il fuoco 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

Compilare e link:

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

Risultato:

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

:

atteso:

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

Come posso fare che regola il fuoco?

È stato utile?

Soluzione

Sembra che si desidera sovrapposizione casi , come si desidera avere un instance Out String che è diverso instance Show a => Out a che si sovrappone esso.

{-# 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 raccomandazione generale è quello di evitare l'uso di istanze che si sovrappongono e le istanze indecidibili a meno che veramente necessari, come i cambiamenti a typechecking che fanno non sono portatili e possono causare altri problemi.


Modifica

Attuazione-saggio, pensare a dizionario per ogni istanza di una classe. << sarà dato il dizionario per l'istanza di Out che si prevede di utilizzare come parametro nascosto. Dal momento che out viene guardato da lì, non c'è spazio per il vostro RULE al fuoco. Se non out erano in typeclass, e era stato chiamato da una funzione non polimorfica, quindi mi aspetterei il RULE da abbinare, ma così com'è, non è sorprendente che non funziona.

RULE / SPECIALIZE sono destinate ad essere solo ottimizzazioni, e il codice non dovrebbe cambiare comportamento se lo fanno o non vengono attivati.

Ci ho messo un po 'a capire quello che stavi facendo ... Ti rendi conto che non è Haskell C ++, giusto? I modi in cui viene utilizzato il polimorfismo è molto diversa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top