문제

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

컴파일 및 링크 :

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

결과:

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

예상되는:

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

그 규칙을 어떻게 화재 할 수 있습니까?

도움이 되었습니까?

해결책

당신이 원하는 것 같습니다 겹치는 인스턴스, 당신이 가고 싶기 때문에 instance Out String 어느 것과 다릅니다 instance Show a => Out a 그것은 그것을 겹칩니다.

{-# 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

일반적인 권장 사항은 겹치는 인스턴스와 명확하지 않은 인스턴스의 사용을 피하는 것입니다. 진심으로 타자기에 대한 변경 사항이 휴대 할 수 없으며 다른 문제를 일으킬 수 있으므로 필요합니다.


편집하다

구현 측면에서 클래스의 각 인스턴스에 대해 사전을 생각하십시오. << 인스턴스에 대한 사전이 제공됩니다 Out 숨겨진 매개 변수로 사용될 것으로 예상됩니다. 부터 out 거기에서 쳐다보고 있습니다. RULE 발사. 만약에 out 타입 클래스에 있지 않았으며 비 폴리 흉부 기능에서 부름을 받았습니다. 그러면 나는 RULE 어울리지 만 그대로 작동하지 않는다는 것은 놀라운 일이 아닙니다.

RULE/SPECIALIZE 최적화 일 뿐이며 코드가 해고를하거나 해고하지 않으면 행동을 변경해서는 안됩니다.

당신이하고있는 일을 깨닫는 데 시간이 걸렸습니다 ... 당신은 Haskell이 C ++가 아니라는 것을 알고 있습니다. 다형성이 활용되는 방식은 상당히 다릅니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top