List 您可以使用(=)<*&燃气轮机;相反。它是如何工作的?
我试着用这些类型来处理这个问题,但是我仍然很难理解它是如何工作的 鉴于:List 您可以使用(=)<*&燃气轮机;相反。它是如何工作的?,list,haskell,reverse,palindrome,List,Haskell,Reverse,Palindrome,我试着用这些类型来处理这个问题,但是我仍然很难理解它是如何工作的 鉴于: > :t (==) (==) :: Eq a => a -> a -> Bool > :t (<*>) (<*>) :: Applicative f => f (a -> b) -> f a -> f b > :t reverse reverse :: [a] -> [a] > :t (==) <*> reve
> :t (==)
(==) :: Eq a => a -> a -> Bool
> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
> :t reverse
reverse :: [a] -> [a]
> :t (==) <*> reverse
(==) <*> reverse :: Eq a => [a] -> Bool
:t(=)
(==)::等式a=>a->a->Bool
>:t()
()::应用程序f=>f(a->b)->f a->f b
>:t倒档
反向::[a]->[a]
>:t(=)反向
(==)反向::等式a=>[a]->Bool
直观地说,我可以理解,它将等式运算符与reverse结合在一起,这样它就创建了一个函数来检查反转列表是否与原始列表相等,但这实际上并没有比已经非常明显的内容更多的信息
有人能更详细地分析一下这里实际发生的事情吗?从
()
特别是,专门用于(>)k
的()
类型为
(<*>) :: (k -> a -> b) -> (k -> a) -> (k -> b)
(==) <*> reverse = \k -> (==) k (reverse k)
= \k -> k == reverse k
()::(k->a->b)->(k->a)->(k->b)
因此,应用程序(==)反向
(<*>) :: (k -> a -> b) -> (k -> a) -> (k -> b)
(==) <*> reverse = \k -> (==) k (reverse k)
= \k -> k == reverse k
(==)反向=\k->(==)k(反向k)
=\k->k==反向k
i、 e.它检查列表是否与其反面相同。Chris Taylor的回答恰好正确,但我发现更直观的另一种看待它的方式是:函数类型的Applicative
实例所做的是:
“Feed”同一参数值到两个参数类型相同的函数李>
将它们的结果与另一个函数相结合
所以基本上,如果你有f::t->a
和g::t->b
,Applicative
实例允许你在a
和b
结果上映射函数h::a->b->c
,前提是f
和g
将被输入相同的参数
因此,请考虑如何以一种不复杂的方式编写回文测试:
palindrome :: Eq a => [a] -> Bool
palindrome xs = xs == reverse xs
xs
在定义的右侧出现两次:一次作为=
的参数,第二次作为反向
的参数。这会自动告诉您,可能有一种方法可以使用(>)t
应用程序实例来消除重复。另一种可能更直观的方法是首先将函数重写为:
palindrome xs = id xs == reverse xs
…其中,id x=x
是标识函数,它只返回其参数(并且是标准库函数)。现在,您可以使用标准的Applicative
习惯用法(fa0…an
)将其改写为:
函数组合最重要的特性之一是,对于任何函数f
:
f . id = f
因此,将其应用于上面的回文
版本,我们得到:
-- Since `f . id = f` for all `f`, then `(==) <$> id` is just `(==)`:
palindrome = (==) <*> reverse
--自'f。id=f`对于所有的`f`,那么`(==)id`就是`(==)`:
回文=(==)反向
你所说的(>)k
是什么意思?一些背景:((>)t
是“一个以t
作为输入的函数”,在你的例子中t
是字符串。的应用程序实例,它接收一个字符串
,并将其传递给第一个函数f
,然后返回另一个函数f'
。它将相同的字符串传递给第二个函数,返回某种类型的值;然后用返回值调用f'
。因此(fg)x==fx(gx)
@amalloy我认为我的很多困惑来自
的类型签名是如何变化的。例如f(a->b)
如何变成(k->a->b)
。为什么(>)k
会出现这种情况?它的类型签名没有改变,而是我们使用了更专门的版本
适用于任何应用程序,就像==
适用于任何等式一样。()::Applicative f=>f(a->b)->f a->f b
,在我们的例子中是f:(->)String)
。因此,我们替换f
,得到():(String->a->b)->(String->a)->(String->b)
。此外,a::String
和b::Bool
,所以():(String->String->Bool)->(String->String)->(String->Bool)
。最后,删除无关的()
,得到()::(String->String->Bool)->(String->String)->String->Bool
。为什么你总是要想出好的、清晰的答案呢?两个月后再回来会更有意义。谢谢
f . id = f
-- Since `f . id = f` for all `f`, then `(==) <$> id` is just `(==)`:
palindrome = (==) <*> reverse