代码之家  ›  专栏  ›  技术社区  ›  Brent.Longborough

Haskell中的类型演绎是如何工作的?

  •  10
  • Brent.Longborough  · 技术社区  · 16 年前

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

    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  
    

    Ord r “以及” Floating r “?(我本以为会有某种自动继承:”Floating“意味着”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)
    

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

    请温柔地使用Haskell n00b。

    2 回复  |  直到 15 年前
        1
  •  12
  •   Rüdiger Hanke shraddha hattimare    16 年前

    Floating 应该对所有浮点数进行分类,包括复数。复数没有顺序。你可以使用 RealFloat 而不是 漂浮 Ord .

    rvalue 使用。这是一个论点 log

    :t log
    

    给予

    log :: (Floating a) => a -> a
    

    必须在 漂浮 漂浮 类型类,不精确 Float 日志 start rate 并与 limit r ,所以 将是 r r 漂浮

     :t random (mkStdGen 100)
    

    这给了你

    random (mkStdGen 100) :: (Random a) => (a, StdGen)
    

    a 在这里。它只知道它必须在打字课上 Random .

        2
  •  2
  •   Jared Updike    16 年前

    在Haskell中,Ord和Floating是独立的或 orthogonal 概念。也许你假设Floating只引用非常特定的类型,比如Double和Float(大多数其他语言都是这种情况)?

    正如Rudiger所指出的,有些类型是Floating类的实例,但它们不是Ord,因为某些浮点类型(如Complex)没有顺序。除了复数之外的另一个例子是向量,你可以定义这些浮点函数,但不能定义任何合理的排序。

    请记住,类型类只是指定必须为类型定义的函数集(如Java或C#中的接口,如果这是一种有帮助的思考方式的话)