【问题标题】:Trying to better understand the (<*>) function of Applicative functors in Haskell试图更好地理解 Haskell 中 Applicative 函子的 (<*>) 函数
【发布时间】:2015-07-30 13:46:16
【问题描述】:

我刚刚完成了 Learn You A Haskell For Great Good 的第 11 章,我希望在继续之前更好地了解 Applicative Functor。我有以下 ghci 代码。

let a = Just (5+) -- Instead of mapping + to Just 5
let b = (3+) <$> a -- I imported Control.Applicative even though most of these modules are deprecated
let c = Just (3+) <*> a -- I expect this to be equivalent to b and :t b, :t c shows that they are the 'same'
a <*> Just 1 -- returns 6 as I expected

现在我希望 b 和 c 是:只是 ((3+) . (5+)) 这意味着我可以这样做:

b <*> Just 1 -- and get 9 as in (3+) $ (5+) 1 or ((3+) . (5+)) 1

但我得到:在交互式 GHCI 命令的 stmt 中使用 'it' 导致 (Num (b0 -> b0)) 没有实例:打印它

问题 1: 如下所示的限制意味着什么:

b :: (Num (a -> a), Num a) => Maybe (a -> a)

我认为这只是意味着 可以从“b”中“提取”(a -> a)。在我的菜鸟头脑中,我知道 Num a 意味着“a”必须是 Num 的一个实例,但 Num (a -> a) 对我来说没有多大意义。是不是说 Maybe 里面的 (a -> b) 必须返回一个 Num 的实例?

问题 2: 我所做的一切在 Applicative 领域不可行吗?是否有任何明显的方法可以打印或查看 'b Just 1' 的结果?

let Just val = b <*> Just 1
:t val -- returns ((Num (t -> t), Num t) => t which tells me that val is an instance of Num but then again I am just a beginner so what do I know?

注意:我有我的 ghci 会话的快照,如有必要,可以添加它们。我阅读了一些相关的帖子,但似乎没有任何启发。

【问题讨论】:

  • 我刚刚尝试将您的第一行代码放入我的 ghci,但 b 的声明已经引发了错误。也许您应该指出您正在使用的 ghc 版本,和/或尝试先获取最新版本。
  • @Magnus GHCi,版本 7.8.3

标签: haskell


【解决方案1】:

当你写作时(展开)

let b = (3+) <$> Just (5+)

根据&lt;$&gt;(就是fmap!)的定义,结果值是:

Just (3 + (5+))

您正在向函数添加一个数字!这就是为什么你会得到奇怪的类型错误。

具体来说,Haskell 正在拼命地假装(5+) 是一个数字:

b :: (Num (a -> a), Num a) => Maybe (a -> a)

意思是,如果有一些疯狂的类型a 其中a(a -&gt; a) 都是Num 的实例,我可以添加它们一起在 Functor 中,就好像它们是数字一样,并给你一个结果Maybe (a -&gt; a)!然而,一般来说,函数不是 Num 类型类的实例,所以一切都会崩溃。

你的意思是写:

let b = ((3+).) <$> Just (5+)

确实如您所愿 (b &lt;*&gt; Just 1 == Just 9)。

【讨论】:

  • 那个,或者($3) &lt;$&gt; Just (5+)
  • 有一个细微的差别:OP 说他们希望b(和c)等于Just ((3+) . (5+)),其类型为Num a =&gt; Maybe (a -&gt; a),而不是Num a =&gt; Maybe a
  • 小心你的括号:Just f a(可能)是一个类型错误。你想要Just (f a)
  • @ClayThomas 是的,这就是我要输入的内容。 Just (3+) ((5+)) 也应该是 Just ((3+) ((5+))),即使这样的事情毫无意义。
  • (3+)(5+)(3+).(5+) 之间存在差异。后者是功能的组合;前者是 应用 (3+)(5+) (这会导致您遇到真正令人困惑的类型错误)。
猜你喜欢
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-20
相关资源
最近更新 更多