gpt4 book ai didi

haskell - 为 Reader r 编写 Applicative 实例时如何编写 <*>

转载 作者:行者123 更新时间:2023-12-04 06:32:53 25 4
gpt4 key购买 nike

我被困在 Haskell Book 中的一个练习中。 ,“第 22 章。读者”。该练习说“为读者实现应用程序”,它给出了以下内容:

{-# LANGUAGE InstanceSigs #-}

newtype Reader r a =
Reader { runReader :: r -> a }

instance Applicative (Reader r) where
pure :: a -> Reader r a
pure a = Reader $ ???

(<*>) :: Reader r (a -> b) -> Reader r a -> Reader r b
(Reader rab) <*> (Reader ra) = Reader $ \r -> ???

我能够写 pure在还写了 Functor 之后实例(我写了 Functor 实例,因为否则 GHC 会提示“ (Functor (Reader r)) … 的实例声明中的实例声明的父类(super class)中没有 ‘Applicative (Reader r)’ 的实例| ”):
{-# LANGUAGE InstanceSigs #-}

newtype Reader r a =
Reader { runReader :: r -> a }

instance Functor (Reader r) where
fmap f (Reader x) = Reader (f . x)

instance Applicative (Reader r) where
pure :: a -> Reader r a
pure a = Reader $ \_ -> a

(<*>) :: Reader r (a -> b) -> Reader r a -> Reader r b
(Reader rab) <*> (Reader ra) = Reader $ \r -> ???

但我坚持使用 ???部分。

书中给出了以下提示:

We got the definition of the apply function started for you, we’ll describe what you need to do and you write the code. If you unpack the type of Reader’s apply above, you get the following.

<*> :: (r -> a -> b) 
-> (r -> a)
-> (r -> b)

-- contrast this with the type of fmap

fmap :: (a -> b)
-> (r -> a)
-> (r -> b)

So what’s the difference? The difference is that apply, unlike fmap, also takes an argument of type r.

Make it so.



是的,但如何做到这一点?使用类型化的孔,编译器告诉我 ??? 的类型必须是 b .但是我仍然看不到如何构造一个接受 r 的 lambda 表达式。并返回 b 类型的内容, 给定 rabra .

最佳答案

让我们打网球吧。看着你范围内的作品,

rab :: r -> (a -> b)
ra :: r -> a
r :: r

b 的目标类型,您可以看到获得 b 的唯一方法通过申请 rab两个论点。
Reader rab <*> Reader ra = Reader $ \r -> rab _ _

现在,第一个孔的类型为 r ,而您只有一个 r在适用范围。
Reader rab <*> Reader ra = Reader $ \r -> rab r _

剩余孔的类型为 a .唯一的 a您在范围内的是 ra 的返回值,
Reader rab <*> Reader ra = Reader $ \r -> rab r (ra _)

ra的参数必须是 r ,对此你再一次只有一个选择。
Reader rab <*> Reader ra = Reader $ \r -> rab r (ra r)

请注意 rabra都收到 r作为论据。组合 Reader 中的所有步骤计算可以访问相同的环境。

顺便说一句,这个定义使得 <*>相当于著名的 S combinator (和 pureK )。

关于haskell - 为 Reader r 编写 Applicative 实例时如何编写 <*>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40060162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com