当使用random-fu 0.3.0.0时,我对探索random
.
检查:t
我得到
ghci> :t Data.Random.sample
Data.Random.sample
:: (Data.Random.Distribution d t, Data.Random.StatefulGen g m,
Control.Monad.Reader.Class.MonadReader g m) =>
d t -> m t
Run Code Online (Sandbox Code Playgroud)
但:i
表现出不同的类型
ghci> :i Data.Random.sample
Data.Random.sample ::
(Data.Random.Sampleable d m t, Data.Random.StatefulGen g m,
Control.Monad.Reader.Class.MonadReader g m) =>
d t -> m t
-- Defined in `Data.Random.Sample'
Run Code Online (Sandbox Code Playgroud)
源代码似乎需要Sampleable
约束。有趣的是,有一条评论要求Distribution
改为。
-- |Sample a random variable using the default source of entropy for the
-- monad in which the sampling occurs.
sample :: (Sampleable d m t, StatefulGen g m, MonadReader g m) => d t -> m t
sample thing = ask >>= \gen -> sampleFrom gen thing
-- |Sample a random variable in a \"functional\" style. Typical instantiations
-- of @s@ are @System.Random.StdGen@ or @System.Random.Mersenne.Pure64.PureMT@.
-- sample :: (Distribution d a, StatefulGen g m, MonadReader g m) => d t -> m t
-- sample thing gen = runStateGen gen (\stateGen -> sampleFrom stateGen thing)
Run Code Online (Sandbox Code Playgroud)
:i
是什么导致和报告的类型之间存在差异:t
?
(我不是问如何使用random-fu
,他们的github中有可以使用的示例)
这是具有更熟悉的约束的同一现象的类似示例:
> f :: (Eq a, Ord a) => a -> Bool; f x = x > x
> :i f
f :: forall a. (Ord a, Eq a) => a -> Bool
> :t f
f :: forall {a}. Ord a => a -> Bool
Run Code Online (Sandbox Code Playgroud)
GHC 注意到Eq
类型中不需要约束,因为Ord
约束已经保证了它*:
> :i Ord
class Eq a => Ord a where
<snip>
Run Code Online (Sandbox Code Playgroud)
你的情况类似,只是课程更复杂。明确说明::i
提供有关程序员编写的定义的信息,准确地重复编写为类型签名的内容(因此仅适用于单独的标识符),同时适用于:t
任何表达式,但运行完整的类型推断算法,包括约束简化。
*您可能想知道它是否注意到没有使用,这就是不需要约束==
的真正原因。Eq
但不是; 将定义更改为f x = x > x || x == x
,并且Eq
约束仍将被省略:t f
。