gpt4 book ai didi

haskell - Haskell 中的 "lifting"是什么?

转载 作者:行者123 更新时间:2023-12-03 04:30:28 28 4
gpt4 key购买 nike

我不明白什么是“提升”。在了解什么是“提升”之前我应该​​首先了解单子(monad)吗? (我对 monad 也完全一无所知:)或者有人可以用简单的话向我解释一下吗?

最佳答案

提升更多的是一种设计模式,而不是数学概念(尽管我希望这里有人现在会通过展示提升如何是一个类别或其他东西来反驳我)。

通常您有一些带有参数的数据类型。类似的东西

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

假设您发现Foo有很多用途采用数字类型( IntDouble 等),您必须不断编写代码来解开这些数字,将它们相加或相乘,然后将它们重新包装起来。您可以通过编写一次展开和包装代码来短路此操作。这个函数传统上被称为“lift”,因为它看起来像这样:

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

换句话说,您有一个函数,它采用两个参数函数(例如 (+) 运算符)并将其转换为 Foos 的等效函数。

现在你可以写了

addFoo = liftFoo2 (+)

编辑:更多信息

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

从观察开始

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

但这与 fmap 完全相同。所以而不是 liftFoo1你会写

instance Functor Foo where
fmap f foo = ...

如果你真的想要完全规律性,你可以说

liftFoo1 = fmap

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

import Control.Applicative

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

(<*>) Foo 的运算符具有类型

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

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

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

同样还有liftAliftA3 。但实际上您并不经常使用它们,因为还有另一个运算符

(<$>) = fmap

这可以让你写:

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

术语myFunction <$> arg1返回一个封装在 Foo 中的新函数:

ghci> :type myFunction
a -> b -> c -> d

ghci> :type myFunction <$> Foo 3
Foo (b -> c -> d)

这又可以使用 (<*>) 应用于下一个参数。 , 等等。因此,现在您不再需要为每个数量提供一个提升函数,而是拥有一个应用程序的菊花链,如下所示:

ghci> :type myFunction <$> Foo 3 <*> Foo 4
Foo (c -> d)

ghci: :type myFunction <$> Foo 3 <*> Foo 4 <*> Foo 5
Foo d

关于haskell - Haskell 中的 "lifting"是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2395697/

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