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

问题

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 ()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 11,723评论 0 17
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,397评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,930评论 18 399
  • 跑步是要减肥滴 但千万别把腿给跑粗了~ PINK说 一般女生跑步多半是什么理由? 当然很多人都是为了爱美咯~ 那么...
    陪跑阅读 3,114评论 0 1
  • 他们说,你是仙,我是魔 他们说,你我最好的结局,就是天地相隔,即便相见,你不记得我,我不认识你 所以,你被锁在那仙...
    唐钰小宝Rani阅读 3,184评论 0 0