注意:这里的完整源代码:https ://gist.github.com/anonymous/7085509
我有以下功能:
tournament n p pop = do
winner <- (\w -> min (n - 1) (floor (log w / log (1-p)))) <$> gaRandom
(flip S.index) winner <$> S.sort <$> seqChoose n pop
如果没有类型签名,编译器会告诉我tournament
签名是:
tournament
:: (Floating a, Ord a1, RealFrac a, Random a) =>
Int -> a -> S.Seq a1 -> StateT GA Data.Functor.Identity.Identity a1
这对我来说看起来不错。但是当我使用它时:
t2 = do
g <- newStdGen
let a = evalState (tournament 5 0.9 (S.fromList [1..10])) (GA g)
return ()
我得到错误:
GA.hs:85:37:
No instance for (Fractional a0) arising from the literal `0.9'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Fractional Double -- Defined in `GHC.Float'
instance Fractional Float -- Defined in `GHC.Float'
instance Integral a => Fractional (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus three others
In the second argument of `tournament', namely `0.9'
In the first argument of `evalState', namely
`(tournament 5 0.9 (S.fromList [1 .. 10]))'
In the expression:
evalState (tournament 5 0.9 (S.fromList [1 .. 10])) (GA g)
这引出了我的第一个问题,为什么不RealFrac
暗示Fractional
?类型签名具有 RealFrac,但错误抱怨缺少 Fractional 的实例。
其次,我将类型签名复制并粘贴回代码中并添加Fractional a
:
tournament
:: (Floating a, Ord a1, RealFrac a, Fractional a, Random a) =>
Int -> a -> S.Seq a1 -> State GA a1
tournament n p pop = do
winner <- (\w -> min (n - 1) (floor (log w / log (1-p)))) <$> gaRandom
(flip S.index) winner <$> S.sort <$> seqChoose n pop
现在我得到的错误是:
GA.hs:88:24:
No instance for (Random a0) arising from a use of `tournament'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Random Bool -- Defined in `System.Random'
instance Random Foreign.C.Types.CChar -- Defined in `System.Random'
instance Random Foreign.C.Types.CDouble
-- Defined in `System.Random'
...plus 33 others
In the first argument of `evalState', namely
`(tournament 5 0.9 (S.fromList [1 .. 10]))'
In the expression:
evalState (tournament 5 0.9 (S.fromList [1 .. 10])) (GA g)
In an equation for `a':
a = evalState (tournament 5 0.9 (S.fromList [1 .. 10])) (GA g)
这现在让我更加困惑,因为我没有类型变量a0
。这导致了我的第二个问题:显然我误解了一些东西,但是什么?