什么是“提升”在Haskell中? [英] What is "lifting" in Haskell?

查看:124
本文介绍了什么是“提升”在Haskell中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白解除是什么。在理解什么是电梯之前,我应该先理解单子吗? (我对monads完全无知:)或者有人可以用简单的语言向我解释它?

更多的是一种设计模式而不是一种数学概念(尽管我希望这里的某个人能够通过展示升降机是一个类别还是某个东西来反驳我)。通常情况下,你有一些数据类型带有参数。就像

  data Foo a = Foo {...这里的东西...} 
Foo
大量使用数字类型(<$ c>

$ c> Int , Double 等等),你必须编写解开这些数字的代码,将它们相加或相乘,然后将它们回绕向上。您可以通过编写一次解包和打包代码来将其短路。此功能传统上称为电梯,因为它看起来像这样:

  liftFoo2 ::(a  - > b  - > ; c) - > Foo a  - > Foo b  - > Foo c 

换句话说,你有一个函数需要两个参数的函数(比如(+)运算符)并将其转换为Foos的等价函数。

所以现在你可以写

  addFoo = liftFoo2(+)

编辑:更多信息



您当然可以拥有 liftFoo3 liftFoo4 等等。然而,这通常是没有必要的。



从观察开始

  liftFoo1 ::(a  - > b) - > Foo a  - > Foo b 

但是,这与 fmap 。所以,而不是 liftFoo1 你可以写出

 实例Functor Foo其中
fmap foo = ...

如果你真的想要完整的规则性,你可以说

  liftFoo1 = fmap 

如果你可以把 Foo 变成一个仿函数,也许你可以使它成为一个可应用的仿函数。事实上,如果您可以编写 liftFoo2 ,那么应用程序实例如下所示:

  import Control.Applicative 

实例Applicative Foo其中
pure x = Foo $ ... - 将'x'包裹在Foo中。
(*)= liftFoo2($)

<$ c $对于Foo,c>(*)运算符的类型为

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

它将包装函数应用于包装值。所以如果你可以实现 liftFoo2 那么你可以用它来写这个。或者你可以直接实现它,而不用担心 liftFoo2 ,因为 Control.Applicative 模块包含了

  liftA2 :: Applicative f => (a→b→c)→> f a  - > f b  - > fc 

同样有 liftA liftA3 。但是你并没有经常使用它们,因为有另一个操作符

$ $ $ $ $ $ $ c $(< $>)= fmap

这让你可以写出:

  result = myFunction< $> arg1 * arg2 * arg3 * arg4 

术语 myFunction< $> arg1 返回一个包含在Foo中的新函数。这又可以使用(<>)等应用于下一个参数。因此,现在不必为每个元素提供一个升降功能,而只需要一个菊花链应用程序。


I don't understand what "lifting" is. Should I first understand monads before understanding what a "lift" is? (I'm completely ignorant about monads, too :) Or can someone explain it to me with simple words?

解决方案

Lifting is more of a design pattern than a mathematical concept (although I expect someone around here will now refute me by showing how lifts are a category or something).

Typically you have some data type with a parameter. Something like

data Foo a = Foo { ...stuff here ...}

Suppose you find that a lot of uses of Foo take numeric types (Int, Double etc) and you keep having to write code that unwraps these numbers, adds or multiplies them, and then wraps them back up. You can short-circuit this by writing the unwrap-and-wrap code once. This function is traditionally called a "lift" because it looks like this:

liftFoo2 :: (a -> b -> c) -> Foo a -> Foo b -> Foo c

In other words you have a function which takes a two-argument function (such as the (+) operator) and turns it into the equivalent function for Foos.

So now you can write

addFoo = liftFoo2 (+)

Edit: more information

You can of course have liftFoo3, liftFoo4 and so on. However this is often not necessary.

Start with the observation

liftFoo1 :: (a -> b) -> Foo a -> Foo b

But that is exactly the same as fmap. So rather than liftFoo1 you would write

instance Functor Foo where
   fmap foo = ...

If you really want complete regularity you can then say

liftFoo1 = fmap

If you can make Foo into a functor, perhaps you can make it an applicative functor. In fact, if you can write liftFoo2 then the applicative instance looks like this:

import Control.Applicative

instance Applicative Foo where
   pure x = Foo $ ...   -- Wrap 'x' inside a Foo.
   (<*>) = liftFoo2 ($)

The (<*>) operator for Foo has the type

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

It applies the wrapped function to the wrapped value. So if you can implement liftFoo2 then you can write this in terms of it. Or you can implement it directly and not bother with liftFoo2, because the Control.Applicative module includes

liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

and likewise there are liftA and liftA3. But you don't actually use them very often because there is another operator

(<$>) = fmap

This lets you write:

result = myFunction <$> arg1 <*> arg2 <*> arg3 <*> arg4

The term myFunction <$> arg1 returns a new function wrapped in Foo. This in turn can be applied to the next argument using (<*>), and so on. So now instead of having a lift function for every arity, you just have a daisy chain of applicatives.

这篇关于什么是“提升”在Haskell中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆