Haskell 需要知道什么<*&燃气轮机<$&燃气轮机;和。你在哈斯克尔干什么

Haskell 需要知道什么<*&燃气轮机<$&燃气轮机;和。你在哈斯克尔干什么,haskell,Haskell,这些运营商在做什么 (.) :: (b -> c) -> (a -> b) -> a -> c (<$>) :: Functor f => (a -> b) -> f a -> f b (<*>) :: Applicative f => f (a -> b) -> f a -> f b (::(b->c)->(a->b)->a->c ()::函子f=>(a->b)->f a->f b ()::

这些运营商在做什么

(.) :: (b -> c) -> (a -> b) -> a -> c
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
(::(b->c)->(a->b)->a->c
()::函子f=>(a->b)->f a->f b
()::应用程序f=>f(a->b)->f a->f b
我不知道什么时候看到签名。也许一些简单易懂的解释会对我有所帮助。

操作符由
(..
操作符组成。例如,
\x->f(gx)
f相同。g
。您可以对任意函数执行此操作,例如
\x->f(g(hx))
等于
f。Gh


未根据功能定义
运算符。它们的功能取决于应用它们的实际类型
f
运算符是
函子
库中的
fmap
函数的替代选项。例如,对于
Maybe
类型,它采用左操作数,并且仅当右操作数是
Just
值时才应用它。因此,为了了解这些运算符的作用,只需查看特定类型的实现。

我也在学习Haskell,我的建议是查看,更准确地说:

  • 对于
    ()
    读取
  • 对于
    阅读
实质上:

  • ()
    是函数组合:如果你有
    g::a->b
    f::b->c
    ,那么
    f。g
    本质上是
    f(g(x))
    :首先在
    a
    上使用
    g
    获得
    b
    ,然后在
    b
    上使用
    f
    获得
    c

  • 接受一个接受
    a
    并返回a
    b
    的函数,以及一个包含
    a
    的函子,然后返回一个包含
    b
    的函子。所以
    fmap::(a->b)->fa->fb

  • 接受一个函子,该函子包含一个接受
    a
    并返回
    b
    的函数;接受一个函子,该函子包含
    a
    ,并返回一个包含
    b
    的函子。因此,
    从一个函子中提取函数,并将其应用于一个函子中的参数,最后将结果返回到一个函子中


注意你在书的章节中找到的解释比我在上面的尝试要好

虽然
的常用用法由于它们在一个typeclass中而变得模糊,但是你通常可以阅读haddock文档来了解这些信息。如果您很难找到函数属于哪个模块,请使用。

我是Haskell的新手,有时Haskell类型声明也会让我感到困惑

一开始很容易迷路,因为教程说
大写
命名约定通常用于类型声明,而
camelCase
命名约定通常用于变量

实际上,这属于Haskell中的一种更高技术,可能是多态性。只要把
f
a
b
看作某种类型的变量——处理类型的变量。Haskell中的
class
不是面向对象的,而是面向
type
。所以
函子f
意味着类型
f
属于
类函子,依此类推

如果将这些字母
a
b
c
替换为某种类型,称为
实例
,例如
字符串
字符
。这将是有意义的:

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

也许您可以通过示例学习(就像我一样),因此这里有一些简单的示例,您可以在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
(.)函数组合
--(::(b->c)->(a->b)->a->c
>f=(+1)
>g=(*2)
>a=f。G
>a 0
1--f(g(0))或(0*2)+1
>b=g。F
>b 0
2--g(f(0))或(0+1)*2
-函子
--()::函子f=>(a->b)->f a->f b
>a=(*2)
>b=4
>a b
只有8个
-实用的
--()::应用程序f=>f(a->b)->f a->f b
>a=仅(*2)
>b=4
>a b
只有8个

我希望这能有所帮助。

关于前两个问题,请参见答案:顺便说一句,
(.)=()
,因此您只需要学习其中两个;)@fuzzxl:仅在
(>)r
函子:)。@fuzzxl
()=fmap
,当然
fmap
()
不一样。“亚当斯是对的。@安德烈,谢谢你回答我一年半前的评论
()
()
的专用版本。在阅读了LYAH之后,这个问题的答案也是很好的。下面是另一个例子([(*2),(+10)][1,2,3])==[2,4,6,11,12,13]