추론 된 유형 서명이 내가 기대했던 것과 다른 이유를 이해하는 데 약간의 어려움이 있습니다.유추 추세 유형
import Control.Applicative
import Data.Word
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Token
import Text.Parsec.Language (emptyDef)
import Text.Parsec.Prim
import Data.Functor.Identity
--parseUInt' :: Num b => ParsecT String u Identity b
parseUInt' = fromInteger <$> decimal (makeTokenParser emptyDef)
--parseUInt1 = fromInteger <$> decimal (makeTokenParser emptyDef)
--parseUInt2 = fromInteger <$> decimal (makeTokenParser emptyDef)
parsePairOfInts = do
x <- parseUInt'
char ','
y <- parseUInt'
return $ (x, y)
parseLine :: String -> Either ParseError (Word32, Word8)
parseLine = parse parsePairOfInts "(error)"
main = print . show $ parseLine "1,2"
이 코드는 컴파일되지 않습니다 :
test.hs:21:19:
Couldn't match type ‘Word32’ with ‘Word8’
Expected type: Parsec String() (Word32, Word8)
Actual type: ParsecT String() Identity (Word32, Word32)
In the first argument of ‘parse’, namely ‘parsePairOfInts’
In the expression: parse parsePairOfInts "(error)"
Failed, modules loaded: none.
을하지만 parseUInt'
의 유형 서명의 주석을 경우는 잘 컴파일의 예로 들어 보자 (I는 가능한 한 짧게 만들려고).
λ>:t (fromInteger <$> decimal (makeTokenParser emptyDef))
(fromInteger <$> decimal (makeTokenParser emptyDef))
:: Num b => ParsecT String u Identity b
을하지만 명시 적으로 타입 서명을 지정하지 않을 경우, 'B'유형은 어떻게 든 Word32
에 고정되어있다 : 나는 GHCi에서 형식 정보를 조회 할 경우 동시에
을 두 개의 다른 (그러나 여전히 동일한 구현) 함수 parseUInt1
및 parseUInt2
으로 바꾸면 코드도 컴파일됩니다.
함수의 유형을 지정하지 않으면 추론 된 유형이 가장 제한 적이 지 않아야한다고 생각했지만 (어쨌든이 경우는 그렇지 않습니다.)
내가 실제로 여기에없는 이유는 무엇입니까?
이것은 [Monomorphism restriction] (http://www.haskell.org/haskellwiki/Monomorphism_restriction)입니다. '{- # LANGUAGE NoMonomorphismRestriction # -}'을 추가하면 컴파일이 시작됩니다. @ GabrielGonzalez 및 @amalloy에게 감사드립니다. 난 당신의 대답을 upvote 수 있지만 아직 충분한 "명성"을 갖고 싶지 않아요. –