美文网首页Haskell
[Haskell] 签名限制了类型推导

[Haskell] 签名限制了类型推导

作者: 何幻 | 来源:发表于2017-07-11 11:01 被阅读15次

    问题

    fix :: (a -> a) -> a
    fix g = let x = g x in x
    
    w = \f -> \n -> case n of 
      1 -> print 1
      n -> do
        f(n-1)
        print n
    
    fix w 10    -- 可以得到结果 ()
    

    但是如果给w加上类型签名,编译器就会报错,

    w :: (Int -> IO Int) -> Int -> IO ()
    
    fix w 10
    

    Couldn't match type ‘()’ with ‘Int’
    Expected type: (Int -> IO ()) -> Int -> IO ()
    Actual type: (Int -> IO Int) -> Int -> IO ()
    In the first argument of ‘fix’, namely ‘w’
    In the expression: fix w 10

    原因

    wfix的第一个参数,所以类型应该为a -> a
    w写上类型签名之后,w的类型为(Int -> IO Int) -> Int -> IO (),与a -> a矛盾,所以报错。

    不给w显式写类型签名,则w的类型可以推断为(Int -> IO x) -> Int -> IO ()
    其中Int -> IO xf的类型,f的返回值类型是无法推断的。

    在do-notation中,

    do
        f(n-1)
        print n
    

    f(n-1)相当于省略了ii <- f(n-1)简写,因此f的返回值并没有被其他函数使用,其类型是无法推断的。

    fix w 10中,f的类型最终确定为Int -> IO ()
    此时w的类型为(Int -> IO ()) -> Int -> IO (),与a -> a并不矛盾,其中aInt -> IO ()

    相关文章

      网友评论

        本文标题:[Haskell] 签名限制了类型推导

        本文链接:https://www.haomeiwen.com/subject/iymphxtx.html