":i"如何显示与":t"不同的类型?



当使用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

: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'

源代码似乎需要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)

是什么导致了: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

GHC 注意到类型中不需要Eq约束,因为Ord约束已经保证了这一点*

> :i Ord
class Eq a => Ord a where
<snip>

你的情况是相似的,只是类更复杂。 明确说明::i提供有关程序员编写的定义的信息,准确地回馈作为类型签名编写的内容(因此仅适用于单独的标识符),而:t适用于任何表达式,但运行完整的类型推断算法,包括约束简化。

*您可能想知道它是否注意到未使用==,这是不需要Eq约束的真正原因。但是没有;将定义更改为f x = x > x || x == xEq约束仍将从:t f中省略。

相关内容

  • 没有找到相关文章

最新更新