使用Applicative和Functor的Haskell函数

使用Applicative和Functor的Haskell函数,haskell,Haskell,我有一个练习问题,在这里我得到一个函数: sequence :: Applicative f => [f a] -> f[a] sequence = foldr (_hole (:)) (pure []) 问题是: "What type is required for the function that needs to be placed at _hole in the following expression? Also give a definition for the

我有一个练习问题,在这里我得到一个函数:

sequence :: Applicative f => [f a] -> f[a]
sequence = foldr (_hole (:)) (pure [])
问题是:

"What type is required for the function that needs to be placed at 
_hole in the following expression? Also give a definition for the 
expression using  and <$> and <*>".
我在理解问题的含义方面有困难。因此,对于我所尝试的,我假设需要指定操作符,因为它使用foldr,所以我假设它类似于sequence=foldr+:pure[]

对于表达式的定义,我写了如下内容:

sequence :: <*> f => [f a] -> f[a]
sequence = foldr <$> pure []

我很确定我不是100%正确的,因此希望在这方面得到一些帮助,以便进行任何更正。

本练习希望您假设某个值洞在某个地方定义,并且上面的代码进行了类型检查。然后,目标是确定该洞的类型。然后,它会要求一个可能的定义为_洞

例如,如果我们

foo :: Int
foo = 3 + _hole
答案应该是_-hole::Int,因为这就是我们需要让上面的代码工作的原因。对于定义_hole=2是可以的

相反,在

foo :: Int -> Bool
foo = const _hole "hello" True
然后我们需要_-hole::Bool->Int->Bool,例如_-hole=\b i->b

您自己的代码更复杂,因此最好写下所有步骤:

sequence :: Applicative f => [f a] -> f[a]
sequence = foldr (_hole (:)) (pure [])
此处使用foldr,列表上的类型为

foldr :: (b -> c -> c) -> c -> [b] -> c
要进行类型检查,参数必须具有类型

_hole (:) :: b -> c -> c
pure [] :: c
foldr的结果是,仅使用两个参数调用

sequence :: [b] -> c
因为这必须与上面的序列类型匹配,所以我们得到

[b] = [f a]
c = f [a]
因此,b=fa和

纯[]零件类型按原样进行检查。另一方面,我们需要

_hole :: (type of (:)) -> f a -> f [a] -> f [a]
i、 e.因为:::d->[d]->[d]对于任何d,我们都得到

其中d可以任意选取。不过,选择d=a是很自然的,这样我们就可以

_hole :: (a -> [a] -> [a]) -> f a -> f [a] -> f [a]

现在,我们需要写一个定义_holef x y=??在和方面。本质上,我们需要从库中重新实现liftA2。您现在应该能够解决最后一部分了。

本练习希望您假设某个值洞在某个地方定义,并且上面的代码会进行类型检查。然后,目标是确定该洞的类型。然后,它会要求一个可能的定义为_洞

例如,如果我们

foo :: Int
foo = 3 + _hole
答案应该是_-hole::Int,因为这就是我们需要让上面的代码工作的原因。对于定义_hole=2是可以的

相反,在

foo :: Int -> Bool
foo = const _hole "hello" True
然后我们需要_-hole::Bool->Int->Bool,例如_-hole=\b i->b

您自己的代码更复杂,因此最好写下所有步骤:

sequence :: Applicative f => [f a] -> f[a]
sequence = foldr (_hole (:)) (pure [])
此处使用foldr,列表上的类型为

foldr :: (b -> c -> c) -> c -> [b] -> c
要进行类型检查,参数必须具有类型

_hole (:) :: b -> c -> c
pure [] :: c
foldr的结果是,仅使用两个参数调用

sequence :: [b] -> c
因为这必须与上面的序列类型匹配,所以我们得到

[b] = [f a]
c = f [a]
因此,b=fa和

纯[]零件类型按原样进行检查。另一方面,我们需要

_hole :: (type of (:)) -> f a -> f [a] -> f [a]
i、 e.因为:::d->[d]->[d]对于任何d,我们都得到

其中d可以任意选取。不过,选择d=a是很自然的,这样我们就可以

_hole :: (a -> [a] -> [a]) -> f a -> f [a] -> f [a]

现在,我们需要写一个定义_holef x y=??在和方面。本质上,我们需要从库中重新实现liftA2。您现在应该能够解决最后一部分了。

让我们一步一步地解决,逐步发现定义中涉及的实体类型。我们被给予

sequence :: Applicative f => [f a] -> f [a]               --  (1)
sequence = foldr (_hole (:)) (pure [])                    --  (2)
对于某些g,序列=mkg:

所以我们有,

\ _B _C _D -> ((_B <*> _C) <*> _D)  
          :: f (a -> (t  ->  s)) -> f a -> f  t  -> f  s
   g ((:) ::    a -> [a] -> [a]) :: f a -> f [a] -> f [a]

让我们一步一步地做,逐步发现定义中涉及的实体类型。我们被给予

sequence :: Applicative f => [f a] -> f [a]               --  (1)
sequence = foldr (_hole (:)) (pure [])                    --  (2)
对于某些g,序列=mkg:

所以我们有,

\ _B _C _D -> ((_B <*> _C) <*> _D)  
          :: f (a -> (t  ->  s)) -> f a -> f  t  -> f  s
   g ((:) ::    a -> [a] -> [a]) :: f a -> f [a] -> f [a]

问题是告诉你_-hole是一个函数,然后问你它必须有什么类型才能进行类型检查。假设序列定义中的所有其他内容都是正确的,并且您不会更改它。此外,您不需要为_-hole实现。也许下一个问题会问这个问题。一旦你弄清楚了类型,实现就相当简单了。问题是告诉你_-hole是一个函数,然后问你它必须有什么类型才能对定义进行类型检查。假设序列定义中的所有其他内容都是正确的,并且您不会更改它。此外,您不需要为_-hole实现。也许下一个问题会问这个问题。一旦确定了类型,实现就相当简单了。