简体   繁体   English

Haskell:我不知道如何匹配类型

[英]Haskell: I don't know how to match types

So, I have this Haskell question to resolve: 因此,我有一个Haskell问题可以解决:

Define a mapIO function that receives a function f and an input and output action a and results in an input and output action that, when executed, performs the given action a and returns the application of f to the return of a . 定义一个mapIO函数,该函数接收函数f和输入输出动作a并产生输入输出动作,该输入输出动作在执行时执行给定动作a并将f的应用返回到a的返回。

Here's my code: 这是我的代码:

mapIO f a = do b <- a
               return f(b);

It compiles but it doesn't work. 它可以编译,但是不起作用。 When I try to do the same as the following execution example, it doesn't work. 当我尝试执行与以下执行示例相同的操作时,它不起作用。 Please, can someone help me? 拜托,有人可以帮我吗?

Prelude Data.Char> mapIO even readLn
75
False

In many other languages, g(x) is the syntax for applying function g to argument x . 在许多其他语言中, g(x)是将函数g应用于参数x的语法。 In Haskell, juxtaposition suffices, so that gx applies g to x . 在Haskell中,并置就足够了,因此gxg应用于x By coincidence, this means g(x) is also valid syntax that applies g to the value (x) , which is the same as x , so to a beginner it may seem that g(x) is the correct syntax for function application. 碰巧的是,这意味着g(x) 也是g应用于值(x)有效语法,该值与x相同,因此对于初学者来说, g(x)似乎是函数应用程序的正确语法。 But it ain't, and that confusion has bitten you here. 但是事实并非如此,这种困惑在这里刺痛了您。

When you write return f(b) , you probably assume this means to use the special syntax return and the thing to return should be the function application f(b) . 在编写return f(b) ,您可能会认为这意味着使用特殊语法return ,而return的东西应该是函数application f(b) However, return is itself a function in Haskell. 但是, return本身是Haskell中的一个函数。 So what it actually means is to apply return to the function f , then apply the result to the term (b) . 因此,实际上意味着将return应用于函数f ,然后将结果应用于项(b) (Function application is "left-associative" in that sense.) (从这个意义上讲,功能应用程序是“左关联”的。)

Luckily the fix for function application associativity problems, as with other associativity problems, is to use parentheses. 幸运的是,与其他关联性问题一样,函数应用程序关联性问题的解决方法是使用括号。 So: 所以:

return (f(b))

Or, without the coincidentally correct extra parentheses: 或者,在没有巧合的情况下,没有额外的括号:

return (f b)

This leaves only the question of why it "worked" (in the sense of compiled and type-checked) in return f(b) form. 这仅留下了一个问题,为什么它以return f(b)形式“工作”(就编译和类型检查而言)。 This is a bit of an advanced topic; 这是一个高级话题。 but it turns out that functions also form a Monad with return = const , and so return f(b) actually meant const f(b) , which threw away the (b) term. 但是事实证明,函数还可以通过return = const构成Monad ,因此return f(b)实际上意味着const f(b) ,从而舍弃了(b)项。 (Aside: in addition to being allowed to use the function instance of Monad , we also must be using the function instance of Monad here. Since we are applying return f to (b) , the type of return f must be a function.) So your definition was the same as: (除了:除了被允许使用Monad的函数实例,我们还必须在这里使用Monad的函数实例。由于我们将return f应用于(b)return f的类型必须是一个函数。)因此,您的定义与:

mapIO' f a = do b <- a
                f

That is: first do a , throw away its result, then do f as if it were another input/output action . 也就是说:首先执行a ,丢弃其结果,然后执行f ,就好像它是另一个输入/输出操作一样 If you check the type inferred for mapIO you will see it matches this intuition: 如果检查为mapIO推断的类型,您将看到它与以下直觉相符:

mapIO :: Monad m => m b -> m t -> m b

Whoops! 哎呀!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM