如何解决应用风格的动作之间的交流
Haskell设计模式,编写此示例:
(+) <$> Nothing <*> Just 10 <*> Just 20
证明应用风格的动作之间的沟通有限。
问题是我无法在ghci中编译此示例,但出现错误:
<interactive>:28:1: error:
• Non type-variable argument in the constraint: Num (a -> b)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall a b. (Num (a -> b),Num a) => Maybe b
解决方法
该示例是错误的。其中任何一项工作:
Prelude> (+) <$> Nothing <*> Just 10
Nothing
Prelude> (+) <$> Just 10 <*> Just 20
Just 30
Prelude> (+) <$> Just 20 <*> Nothing
Nothing
但是给定的一个没有,因为(+)
只有两个参数。
将其用作(+)<$>_<*>_<*>_
意味着编译器将尝试推断其中(+)
具有三个参数的类型。嗯,这并不是完全不可思议的,因为Haskell多参数函数实际上是一个参数的函数会产生另一个参数的函数,从而产生...
因此,“双参数函数” a -> a -> a
原则上,如果使用函数类型实例化a
本身,则会有更多参数。说a ~ (Int -> Int)
,然后
(+) :: Num (Int -> Int) => (Int -> Int) -> (Int -> Int) -> Int -> Int
┗━━━━━━━━━━┛ ┗━━━━━━━━━━┛ ┗━┛
Voilà,三个论点。问题是Int -> Int
或更普遍的a->b
不是数字类型,即Num (a -> b)
不是可以满足的约束,尽管有人可以想到 >可以编写这样的实例。
请注意,有时Monoid (a,b)
约束是有意义的,GHC确实允许它们,但是您需要遵循建议并通过以下方式启用FlexibleContexts
扩展名:将{-# LANGUAGE FlexibleContexts #-}
放在源文件的顶部,或者将:set -XFlexibleContexts
放在GHCi中。在您的示例中,这根本没有帮助。
要将(+)
应用于任意数字或参数,可以将其折叠在列表上:
> :m +Data.List
> foldl1 (+) [0,10,20]
30
同样,您可以将应用提升格式(liftA2 (+) p q ≡ (+)<$>p<*>q
)折叠在Maybe-numbers列表上:
> :m +Control.Applicative
> foldl1 (liftA2(+)) [Nothing,Just 10,Just 20]
Nothing
> foldl1 (liftA2(+)) [Just 0,Just 20]
Just 30
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。