我需要知道〈*>〈$>和.在haskell做什么

8fsztsew  于 2022-12-19  发布在  其他
关注(0)|答案(5)|浏览(118)

这些操作员在做什么?

(.) :: (b -> c) -> (a -> b) -> a -> c
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b

我看到签名时没有任何想法。也许一些简单易懂的例子会帮助我。

0g0grzrc

0g0grzrc1#

我也在学习Haskell,我的建议是研究一下Learn You a Haskell for Great Good!,更确切地说:

  • (.)改为功能组成
  • 对于<$><*>,请读取应用函子

实质上:

  • (.)为函数组成:如果有g :: a -> bf :: b -> c,那么f . g本质上就是f(g(x)):首先在a上使用g获得b,然后在该b上使用f获得c
  • <$>接受一个接受a并返回b的函数,以及一个包含a的函子,并且它返回一个包含b的函子,所以<$>fmap :: (a -> b) -> f a -> f b相同
  • <*>接受一个函子,这个函子包含一个接受a并返回b的函数,以及一个包含a的函子,它返回一个包含b的函子,所以<*>从一个函子中提取函数,并将其应用于一个函子内部的参数,最后将结果返回到函子中
    注意你在书中章节中找到的解释比我上面的尝试要好
gojuced7

gojuced72#

也许你是通过例子学习的(就像我一样),所以这里有一些简单的例子,你可以在GHCI中随意摆弄。

(.) - Function Composition 
-- (.) :: (b -> c) -> (a -> b) -> a -> c
> f = (+1)
> g = (*2)
> a = f . g
> a 0
1 -- f( g( 0 ) ) or (0 * 2) + 1
> b = g . f
> b 0
2 -- g( f( 0 ) ) or (0 + 1) * 2

<$> - Functor
-- (<$>) :: Functor f => (a -> b) -> f a -> f b
> a = (*2)
> b = Just 4
> a <$> b
Just 8

<*> - Applicative
-- (<*>) :: Applicative f => f (a -> b) -> f a -> f b
> a = Just (*2)
> b = Just 4
> a <*> b
Just 8

希望能有所帮助。

umuewwlo

umuewwlo3#

(.)运算符组合函数。例如,\x -> f (g x)f . g相同。您可以对任意函数执行此操作,例如\x -> f (g (h x))等于f . g . h
<$><*>运算符不是根据功能定义的。它们的功能取决于应用它们的实际类型f<$>运算符是Functor库中fmap函数的替代。例如,对于Maybe类型,它取左操作数,并且仅当右操作数是Just值时才应用它。因此,为了了解这些操作符的作用,只需查看特定类型的实现。

rmbxnbpk

rmbxnbpk4#

我是Haskell的新手,有时候Haskell的类型声明也让我很困惑。
一开始很容易迷失方向,因为教程说Capitalization命名约定通常用于类型声明,而camelCase命名约定通常用于变量。
实际上,这在Haskell中属于更高级的技术,可能是多态性。只要把fab看作某种类型变量--处理类型 * 的 * 变量。而Haskell中的class不是像OOP那样用于Object,而是用于type。所以Functor f意味着类型f属于class Functor等等。
如果你把这些字母abc替换成某种类型-- * 叫做 * instance--例如StringIntChar

(.) :: (Int -> Char) -> (String -> Int) -> String -> Char
(<$>) :: Functor Maybe => (String -> Int) -> Maybe String -> Maybe Int -- type `Maybe` belongs to class `Functor`
...
tyky79it

tyky79it5#

虽然<$><*>的常见用法被它们在一个类型类中的事实所掩盖,但是你通常可以阅读haddock文档来获得这方面的信息,如果你很难找到一个函数属于哪个模块,可以使用Hoogle

相关问题