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

时间:2017-12-05 19:06:30

标签: haskell

所以,我要解决这个Haskell问题:

定义一个mapIO函数,它接收一个函数f和一个输入和输出动作a,并产生一个输入和输出动作,当执行时,它执行给定的动作{{ 1}}并将a的应用程序返回到f的返回值。

这是我的代码:

a

它编译但不起作用。当我尝试执行与以下执行示例相同的操作时,它不起作用。拜托,有人可以帮帮我吗?

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

1 个答案:

答案 0 :(得分:8)

在许多其他语言中,g(x)是将函数g应用于参数x的语法。在Haskell中,并置就足够了,因此g xg应用于x。巧合的是,这意味着g(x) 也是有效的语法,将g应用于值(x),与x相同,所以初学者似乎g(x)是函数应用程序的正确语法。但它不是,而且这种困惑在这里咬了你。

当您编写return f(b)时,您可能会认为这意味着使用特殊语法return并且要返回的东西应该是函数应用程序f(b)。但是,return本身就是Haskell中的一个函数。所以它实际上意味着将return应用于函数f,然后将结果应用于术语(b)。 (在这种意义上,功能应用是&#34;左关联&#34;)

幸运的是,与其他关联性问题一样,函数应用程序关联性问题的修复是使用括号。所以:

return (f(b))

或者,没有巧合正确的额外括号:

return (f b)

这只留下了为何&#34;工作的问题&#34; (在编译和类型检查的意义上)return f(b)形式。这是一个高级主题;但事实证明,函数也与Monad形成return = const,因此return f(b)实际上意味着const f(b),它会丢弃(b)项。 (除此之外:除了允许使用Monad的函数实例外,我们还必须在这里使用Monad的函数实例。由于我们将return f应用于(b),因此return f的类型必须是函数。)因此,您的定义与以下内容相同:

mapIO' f a = do b <- a
                f

即:首先执行a,抛弃其结果,然后执行f ,就像它是另一个输入/输出操作一样。如果你检查mapIO的推断类型,你会发现它符合这种直觉:

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

糟糕!

相关问题