Type Deduction如何在Haskell中运行?

Bre*_*ugh 10 haskell types type-inference

我试图通过学习Haskell来拓宽思路.

我自己造成的家庭作业是建立一个时钟滴答发生器,它会给我泊松分布的间隔,最终结果(经过长时间的斗争,我承认)是这样的:

import System.Random
poissonStream :: ( Ord r, Random r, Floating r, RandomGen g) => r -> r -> r -> g -> [r]
poissonStream rate start limit gen 
        | next > limit = [] 
        | otherwise     = next:(poissonStream rate next limit newGen)
        where  (rvalue, newGen) = random gen
               next = start - log(rvalue) / rate  
Run Code Online (Sandbox Code Playgroud)

但有两件事(至少)我不明白:

为什么我需要" Ord r"以及" Floating r"?(我本来期望某种自动继承:"浮动"意味着"Ord".)

通过什么路径rvalue :: Float实现了隐含的类型定义?在GHCi中,我得到了我的预期:

*Main System.Random> let (rvalue, newGen) = random (mkStdGen 100)
<interactive>:1:23:
    Ambiguous type variable `t' in the constraint:
      `Random t' arising from a use of `random' at <interactive>:1:23-43
    Probable fix: add a type signature that fixes these type variable(s)
Run Code Online (Sandbox Code Playgroud)

rvalue是一个松散的大炮,我必须绑定:

*Main System.Random> let (rvalue, newGen) = random (mkStdGen 100) :: (Float, StdGen)
*Main System.Random> rvalue
0.18520793
Run Code Online (Sandbox Code Playgroud)

请温柔地使用Haskell n00b.

Rüd*_*nke 12

为什么我需要"Ord r"以及"Floating r"?(我本来期望某种自动继承:"浮动"意味着"Ord".)

Floating应该对所有浮点数进行分类,包括复数浮点数.没有复杂数字的排序.您可以使用RealFloat而不是Floating,这意味着Ord.

通过什么路径隐含的类型定义"rvalue :: Float"实现了?

那么你可以从使用的上下文中推断出它rvalue.它的参数log,并

:t log
Run Code Online (Sandbox Code Playgroud)

log :: (Floating a) => a -> a
Run Code Online (Sandbox Code Playgroud)

所以rvalue必须在Floating类中(因此它将是"类型类中的某种Floating类型,而不是精确的类型Float).此外,结果log与其输入的类型相同,并且在计算中使用startrate与之limit进行比较型的r,所以rvalue将是r(这是合适的,因为rFloating为好).

在GHCi示例中,没有更多上下文.类型

 :t random (mkStdGen 100)
Run Code Online (Sandbox Code Playgroud)

这给了你

random (mkStdGen 100) :: (Random a) => (a, StdGen)
Run Code Online (Sandbox Code Playgroud)

GHCi不知道在a这里填写什么类型.它只知道它必须在类型类中Random.