Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function 什么';Haskell中函数和函子的区别是什么?唯一的定义?_Function_Haskell_Functor_Difference - Fatal编程技术网

Function 什么';Haskell中函数和函子的区别是什么?唯一的定义?

Function 什么';Haskell中函数和函子的区别是什么?唯一的定义?,function,haskell,functor,difference,Function,Haskell,Functor,Difference,在Haskell中,当编写函数时,它意味着我们将某个东西(输入)映射到另一个东西(输出)。我试着去理解函子的定义:看起来和普通函子一样 函数被称为函子有什么限制吗 函子是否允许有I/O或任何其他副作用 如果在Haskell中,“一切都是函数”,那么引入“函子”概念有什么意义呢?功能的受限版本,还是功能的增强版本 非常困惑,需要你的建议。 谢谢。首先,Haskell中的“一切都是函数”不是真的。很多东西都不是函数,比如4。或者字符串“vik santata” 在Haskell中,函数是将一些输入映

在Haskell中,当编写函数时,它意味着我们将某个东西(输入)映射到另一个东西(输出)。我试着去理解函子的定义:看起来和普通函子一样

  • 函数被称为函子有什么限制吗
  • 函子是否允许有I/O或任何其他副作用
  • 如果在Haskell中,“一切都是函数”,那么引入“函子”概念有什么意义呢?功能的受限版本,还是功能的增强版本
  • 非常困惑,需要你的建议。
    谢谢。

    首先,Haskell中的“一切都是函数”不是真的。很多东西都不是函数,比如
    4
    。或者字符串“vik santata”

    在Haskell中,函数是将一些输入映射到输出的东西。函数是一个可以应用于其他值以获得结果的值。如果一个值的类型中有一个
    ->
    ,那么它很可能是一个函数(但是这个经验法则有无限多的例外;-)

    以下是一些功能示例(引自GHCI会议):

    以下是一些非函数的例子:

    • 一个(多态)值,可以假定任何类型
      A
      ,前提是该类型是
      Num
      类的成员(例如
      Int
      将是有效类型)。确切的数值将从数字的使用方式推断出来

      请注意,此类型中有
      =>
      ,这与
      ->
      完全不同。它表示“类约束”

    • 函数列表。请注意,它的类型中有一个
      ->
      ,但它不是顶级类型构造函数(顶级类型是
      []
      ,即“列表”):

    函子不是可以应用于值的东西。函子是其值可与
    fmap
    函数一起使用(并由其返回)的类型(前提是
    fmap
    函数符合某些规则,通常称为“定律”)。您可以使用GHCI找到属于
    Functor
    的基本类型列表:

    λ: :i Functor
    [...]
    instance Functor (Either a) -- Defined in ‘Data.Either’
    instance Functor [] -- Defined in ‘GHC.Base’
    instance Functor Maybe -- Defined in ‘GHC.Base’
    [...]
    
    这意味着您可以将
    fmap
    应用于列表,或者
    可能
    值,或者
    任何一个
    值。

    实际上,a是两个函数,但其中只有一个是Haskell函数(我不确定它是否是您怀疑的函数)

  • 类型级函数。Hask类别的类型是具有种类
    *
    的类型,并且函子将此类类型映射到其他类型。您可以使用
    :kind
    查询在ghci中看到函子的这一方面:

    Prelude> :k Maybe
    Maybe :: * -> *
    Prelude> :k []
    [] :: * -> *
    Prelude> :k IO
    IO :: * -> *
    
    这些函数的作用相当无聊:例如,它们映射

    • Int
      可能是Int
    • ()
      IO()
    • String
      [[Char]]
    我这样说并不是说它们把整数映射成整数,或者是整数等等——这不是每个函子都能做到的。我的意思是,它们将类型
    Int
    ,作为单个实体映射到类型
    可能是Int

  • 一种值级函数,将态射(即Haskell函数)映射到态射。目标态射始终在将类型级别函数应用于原始函数的域和余域后产生的类型之间映射。
    此函数是通过
    fmap
    获得的:

    • fmap::(Int->Double)->(可能Int->Double)
    • fmap::(()->Bool)->(IO()->IO Bool)
    • fmap::(Char->String)->String->[String]

  • 要使某些东西成为函子,需要两件事:

    • 容器类型*
    • 将函数从容器转换为函数转换容器的特殊函数
    第一个取决于您自己的定义,但第二个已编码在名为
    Functor
    的“接口”中,转换函数已命名为
    fmap

    因此,您总是从以下内容开始

    data Maybe a = Just a | Nothing
    
    instance Functor Maybe where
        -- fmap :: (a -> b) -> Maybe a -> Maybe b
        fmap f (Just a) = Just (f a)
        fmap _ Nothing = Nothing
    
    另一方面,函数不需要容器来工作,因此它们与函子没有这种关系。另一方面,每个函子都必须实现函数
    fmap
    ,才能赢得自己的名字

    此外,约定要求
    函子
    遵守某些规则,但这不能由编译器/类型检查器强制执行

    *:此容器也可以是幻影类型,例如
    数据代理a=Proxy
    在这种情况下,容器的名称是有争议的,但我仍然会使用该名称

  • 并非Haskell中的所有内容都是函数。非函数包括
    “Hello World”
    (3::Int,'a')
    ,以及
    只是“x”
    。类型包括
    =>
    的对象也不一定是函数,尽管GHC(通常)在其中间表示中将它们转换为函数
  • 什么是函子?给定类别C和D,从C到D的函子f包括从C的对象到D的对象的映射fo和从C的态射到D的态射的映射fm,从而

  • 如果x和y是C中的对象,p是从x到y的态射,那么fm(p)是从fo(x)到fo(y)的态射
  • 如果x是C中的一个对象,id是从x到x的恒等态射,那么fm(id)是从fo(x)到fo(x)的恒等态射
  • 如果x、y和z是C中的对象,p是从y到z的态射,q是从x到y的态射,那么fm(p.q)=fm(p).fm(q),其中点表示态射合成
  • 这与Haskell有什么关系?我们喜欢将Haskell类型和它们之间的Haskell函数视为一个类别。出于各种原因,这只是大致正确的,但它是直觉的有用指南。然后,
    函子
    类表示inje
    λ: :i Functor
    [...]
    instance Functor (Either a) -- Defined in ‘Data.Either’
    instance Functor [] -- Defined in ‘GHC.Base’
    instance Functor Maybe -- Defined in ‘GHC.Base’
    [...]
    
    Prelude> :k Maybe
    Maybe :: * -> *
    Prelude> :k []
    [] :: * -> *
    Prelude> :k IO
    IO :: * -> *
    
    data Maybe a = Just a | Nothing
    
    instance Functor Maybe where
        -- fmap :: (a -> b) -> Maybe a -> Maybe b
        fmap f (Just a) = Just (f a)
        fmap _ Nothing = Nothing