首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >编译器是什么意思?

编译器是什么意思?
EN

Stack Overflow用户
提问于 2017-08-22 07:21:37
回答 4查看 105关注 0票数 2

我有以下的应用表达式,我知道这是错误的:

代码语言:javascript
运行
复制
Prelude> [Just (*2), Just (+9)] <*> [(Just 3),(Just 4), (Just 5)]

编译器抱怨:

代码语言:javascript
运行
复制
<interactive>:2:2: error:
    * Couldn't match expected type `Maybe Integer -> b'
                  with actual type `Maybe (Integer -> Integer)'
    * Possible cause: `Just' is applied to too many arguments
      In the expression: Just (* 2)
      In the first argument of `(<*>)', namely `[Just (* 2), Just (+ 9)]'
      In the expression:
        [Just (* 2), Just (+ 9)] <*> [(Just 3), (Just 4), (Just 5)]
    * Relevant bindings include it :: [b] (bound at <interactive>:2:1)

编译器想说什么?

此错误消息:

代码语言:javascript
运行
复制
* Couldn't match expected type `Maybe Integer -> b'
              with actual type `Maybe (Integer -> Integer)'

意思是表达式的这一部分[Just (*2), Just (+9)]

让我们看看函数(<*>)的签名

代码语言:javascript
运行
复制
(<*>) :: f (a -> b) -> f a -> f b

用上面的ListMaybe类型构造函数替换它:

代码语言:javascript
运行
复制
(<*>) :: [] (Maybe Integer -> b) -> [] (Maybe Integer) -> [] b

b应该有哪种类型的?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-08-22 07:42:07

让我们更小心地替换

代码语言:javascript
运行
复制
(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b
[Just (*2), Just (+9)] :: [Maybe (Int -> Int)]   --wlog
[Just 3, Just 4, Just 5] :: [Maybe Int]

因此,f = [],因此:

代码语言:javascript
运行
复制
(<*>) :: [a -> b] -> [a] -> [b]

但是现在我们要将[a -> b][Maybe (Int -> Int)]相匹配,这是不可能的--一个函数和一个Maybe是不一样的。您正在尝试在两个函式下执行函式应用程式,而不只是一个函式。也就是说,你需要某种类型的东西

代码语言:javascript
运行
复制
f (g (a -> b)) -> f (g a) -> f (g b)

幸运的是,这很容易实现:liftA2 (<*>)

或者,如果您想要更好的东西,您可以使用复合函子Compose [] Maybe

代码语言:javascript
运行
复制
getCompose $ Compose [Just (*2), Just (+9)] <*> Compose [Just 3, Just 4, Just 5]

(但当Compose很酷的时候,您并不是立即将其作为getCompose,而是将它作为您正在编写的任何程序中的一个重要抽象。)

票数 3
EN

Stack Overflow用户

发布于 2017-08-22 07:42:38

编译器引用了代码的这一部分(In the expression: Just (* 2)):

代码语言:javascript
运行
复制
[Just (*2), Just (+9)] <*> [(Just 3),(Just 4), (Just 5)]
 ^^^^^^^^^

它还说,实际的Just (*2)类型是Maybe (Integer -> Integer),但是使用它的方式需要一个Maybe Integer -> b类型的值(对于某些类型的b)。

如果你看看

代码语言:javascript
运行
复制
(<*>) :: f (a -> b) -> f a -> f b

您可以看到,第一个参数必须是应用于函数类型f的某种类型构造函数a -> b。您有一个值列表,所以f[]

因此,第一个参数必须是一个函数列表,但是您拥有的是一个Maybe的列表,这就是为什么这段代码是一个错误。

错误消息的其余部分来自<*>的第二个参数[(Just 3),(Just 4), (Just 5)],它是一个参数列表(用于第一个参数中的函数列表)。也就是说,编译器知道它需要一个f a类型的值,并且您给它[(Just 3),(Just 4), (Just 5)],所以它推导了f = []a = Maybe Integer

因此,第一个参数f (a -> b)的类型变为[] (Maybe Integer -> b) (与[Maybe Integer -> b]相同)。这里b是完全免费的。您可以使用任何您想要的结果类型,并且您将从f b (即[b] (一个结果列表))中得到<*>

票数 3
EN

Stack Overflow用户

发布于 2017-08-22 07:39:22

这里有一个错误的替代:

代码语言:javascript
运行
复制
(<*>) :: [] (Maybe Integer -> b) -> [] (Maybe Integer) -> [] b

[Just (*2), Just (+9)]有以下类型:Num a => [Maybe (a -> a)]

那是因为Listf in (<*>) :: f (a -> b) -> f a -> f b

根据(<*>)的类型,您可以拥有:

代码语言:javascript
运行
复制
[(*2), (+9)] <*> [2, 3]

代码语言:javascript
运行
复制
Just (*2) <*> Just 2

在这些表达式中,[]Maybe将是相应的应用上下文,而不是同时使用(<*>)

以下深奥的表达式将编译:

代码语言:javascript
运行
复制
[(Just (*2) <*>), (Just (+9) <*>)] <*> [(Just 3), (Just 4), (Just 5)]

但我不确定你要找的是什么。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45811310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档