Haskell自定义Fun类型下joinFun函数的正确实现方法咨询
类型推导分析
我们先拆解各部分的类型:
- 自定义类型
Fun i a本质上是对i -> a函数的包装,用F构造器包裹 - 传入
joinFun的参数是F f时,f的类型为i -> Fun i a:输入一个i类型的环境值,返回另一个Fun i a类型的包装函数 - 我们最终要返回
Fun i a类型,也就是需要再包装一个i -> a类型的函数
你之前的写法错误原因是:直接返回f得到的是i -> Fun i a类型,没有完成内层Fun i a的解包和计算,和目标返回类型不匹配。
正确实现
我们只需要构造一个新的包装函数,接收同一个i类型的参数后,先后调用两层函数即可:
joinFun :: Fun i (Fun i a) -> Fun i a joinFun (F f) = F $ \x -> let F innerF = f x -- 调用外层函数得到内层Fun包装,解包拿到innerF :: i -> a in innerF x -- 把同一个参数x传给内层函数,得到a类型结果
也可以简化写成:
joinFun (F f) = F $ \x -> case f x of F g -> g x
这个Fun类型就是Haskell标准库中Reader单子的定义,joinFun就是Reader单子的join实现,核心逻辑就是把两层函数都应用到同一个共享的环境参数上。
内容的提问来源于stack exchange,提问作者neinso
相关产品推荐
相关产品推荐

