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

Sam*_*vas 6 haskell ghc

当使用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中有可以使用的示例

Dan*_*ner 8

这是具有更熟悉的约束的同一现象的类似示例:

> 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