代码之家  ›  专栏  ›  技术社区  ›  xdavidliu

编译时使用haskell“模糊类型变量”,但粘贴到ghci中时效果良好

  •  0
  • xdavidliu  · 技术社区  · 4 年前

    我对Haskell编译器有时如何推断较少类型感到困惑 多态性超出了我的预期,例如在使用无点定义时。

    问题似乎是“单态性限制”,默认为 旧版本的编译器。

    考虑以下Haskell程序:

    {-# LANGUAGE MonomorphismRestriction #-}
    
    import Data.List(sortBy)
    
    plus = (+)
    plus' x = (+ x)
    
    sort = sortBy compare
    
    main = do
      print $ plus' 1.0 2.0
      print $ plus 1.0 2.0
      print $ sort [3, 1, 2]
    

    如果我用 ghc 我没有得到任何错误,可执行文件的输出是:

    3.0
    3.0
    [1,2,3]
    

    如果我改变 main 身体:

    main = do
      print $ plus' 1.0 2.0
      print $ plus (1 :: Int) 2
      print $ sort [3, 1, 2]
    

    我没有得到编译时错误,输出变为:

    3.0
    3
    [1,2,3]
    

    正如预期的那样。但是,如果我试图将其更改为:

    main = do
      print $ plus' 1.0 2.0
      print $ plus (1 :: Int) 2
      print $ plus 1.0 2.0
      print $ sort [3, 1, 2]
    

    我收到一个类型错误:

    test.hs:13:16:
        No instance for (Fractional Int) arising from the literal ‘1.0’
        In the first argument of ‘plus’, namely ‘1.0’
        In the second argument of ‘($)’, namely ‘plus 1.0 2.0’
        In a stmt of a 'do' block: print $ plus 1.0 2.0
    

    尝试拨打电话时也会发生同样的情况 sort 两次不同类型:

    main = do
      print $ plus' 1.0 2.0
      print $ plus 1.0 2.0
      print $ sort [3, 1, 2]
      print $ sort "cba"
    

    产生以下错误:

    test.hs:14:17:
        No instance for (Num Char) arising from the literal ‘3’
        In the expression: 3
        In the first argument of ‘sort’, namely ‘[3, 1, 2]’
        In the second argument of ‘($)’, namely ‘sort [3, 1, 2]’
    
    • 为什么 ghc 突然想到 plus 不是多态的,需要 Int 争论? 唯一的参考 Int 是在 应用程序 属于 ,这有什么关系 当定义明显具有多态性时?
    • 为什么 ghc 突然想到 分类 需要a Num Char 例子

    此外,如果我试图将函数定义放入它们自己的模块中,如:

    {-# LANGUAGE MonomorphismRestriction #-}
    
    module TestMono where
    
    import Data.List(sortBy)
    
    plus = (+)
    plus' x = (+ x)
    
    sort = sortBy compare
    

    编译时出现以下错误:

    TestMono.hs:10:15:
        No instance for (Ord a0) arising from a use of ‘compare’
        The type variable ‘a0’ is ambiguous
        Relevant bindings include
          sort :: [a0] -> [a0] (bound at TestMono.hs:10:1)
        Note: there are several potential instances:
          instance Integral a => Ord (GHC.Real.Ratio a)
            -- Defined in ‘GHC.Real’
          instance Ord () -- Defined in ‘GHC.Classes’
          instance (Ord a, Ord b) => Ord (a, b) -- Defined in ‘GHC.Classes’
          ...plus 23 others
        In the first argument of ‘sortBy’, namely ‘compare’
        In the expression: sortBy compare
        In an equation for ‘sort’: sort = sortBy compare
    
    • 为什么不是 ghc 能够使用多态类型 Ord a => [a] -> [a] 对于 分类 ?
    • 为什么 ghc 对待 plus' 不同地 应该有 多态类型 Num a => a -> a -> a 我真的看不出这有什么不同 从类型 分类 然而,只有 分类 引发错误。

    最后一件事:如果我评论一下 分类 文件编译。然而 如果我试着把它装进去 ghci 并检查我得到的类型:

    *TestMono> :t plus
    plus :: Integer -> Integer -> Integer
    *TestMono> :t plus'
    plus' :: Num a => a -> a -> a
    

    为什么这种类型不适合 多态?


    这是Haskell中关于单态性限制的典型问题 如[元问题]中所述(https://meta.stackoverflow.com/questions/294053/can-we-provide-a-canonical-questionanswer-for-haskells-monomorphism-restrictio).
    0 回复  |  直到 2 年前