Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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
Haskell 什么';参数多态性和高级类型之间的区别是什么?_Haskell_Rust_Higher Kinded Types_Type Theory_Parametric Polymorphism - Fatal编程技术网

Haskell 什么';参数多态性和高级类型之间的区别是什么?

Haskell 什么';参数多态性和高级类型之间的区别是什么?,haskell,rust,higher-kinded-types,type-theory,parametric-polymorphism,Haskell,Rust,Higher Kinded Types,Type Theory,Parametric Polymorphism,我敢肯定他们不一样。然而,我陷入了困境 “锈不支持”更高种类类型(HKT)的常见概念,但 而是提供参数多态性。我试着让我的头绕过去,理解它们之间的区别,但是越来越纠结 据我所知,锈有更高级的种类,至少是最基本的种类。使用“*”符号,HKT确实有一种类型,例如*->*。 例如,可能属于*->*类型,可以在Haskell中这样实现 数据可能a=只是a |什么都没有 这里, 可能是一个类型构造函数,需要应用于具体类型 成为“*”类的具体类型 只有一个和没有是数据构造函数 在关于哈斯克尔的教科书中

我敢肯定他们不一样。然而,我陷入了困境 “锈不支持”更高种类类型(HKT)的常见概念,但 而是提供参数多态性。我试着让我的头绕过去,理解它们之间的区别,但是越来越纠结

据我所知,锈有更高级的种类,至少是最基本的种类。使用“*”符号,HKT确实有一种类型,例如
*->*
。 例如,
可能属于
*->*
类型,可以在Haskell中这样实现

数据可能a=只是a |什么都没有
这里,

  • 可能是一个类型构造函数,需要应用于具体类型
    成为“*”类的具体类型
  • 只有一个
    没有
    是数据构造函数
在关于哈斯克尔的教科书中,这经常被用作一种更高级类型的例子。但是,在Rust中,它可以简单地实现为枚举,毕竟它是一种总和类型:

再说一次,在哈斯凯尔,这大概是

do_something :: Maybe a -> ()
do_something :: Maybe a -> ()
do_something _ = ()
这就引出了第四个问题

  • 对更高级类型的支持到底在哪里结束?有什么问题 使Rust的类型系统无法表示HKT的最小示例
  • 相关问题: 我浏览了很多与主题相关的问题(包括他们与博客帖子的链接等),但我找不到我的主要问题(1和2)的答案

  • 更新 谢谢你提供了很多很好的答案,这些答案都非常详细,帮助很大。我决定接受安德烈亚斯·罗斯伯格的回答,因为他的解释最有助于我走上正轨。特别是术语部分


    我真的陷入了这样一个循环:所有的东西
    *->*…->*是更高级的。强调
    *->*->*
    (*->*)->*
    之间区别的解释对我来说至关重要。

    我将继续说明:更高种类的类型只是类型级别的高阶函数

    但请花一分钟:

    考虑
    monad
    变压器:

    newtype StateT s m a :: * -> (* -> *) -> * -> *
    
    这里,

    什么是高级类型

    m :: (* -> *)
    
    因为接受一种类型
    *
    ,并返回一种类型
    *

    它就像一个类型上的函数,也就是一个类型构造函数

    * -> *
    
    在像Java这样的语言中,你不能这样做

    class ClassExample<T, a> {
        T<a> function()
    }
    
    class类示例{
    T函数()
    }
    
    在Haskell中,T将具有种类
    *->*
    ,但Java类型(即类)不能具有该种类的类型参数,即更高种类的类型

    另外,如果您不知道,在basic Haskell中,表达式的类型必须是kind
    *
    ,即“具体类型”。任何其他类型,如
    *->*


    例如,您不能创建类型为
    的表达式,可能是
    。它必须是应用于参数的类型,比如
    可能是Int
    可能是String
    ,等等。换句话说,是完全应用的类型构造函数。

    Rust不能做的一个简单示例是Haskell的
    Functor

    类函子f,其中
    fmap::(a->b)->f a->f b
    --举几个例子:
    实例函子可能在哪里
    --fmap::(a->b)->可能a->可能b
    fmap uuo无=无
    fmap f(正好x)=正好(fx)
    实例函子[],其中
    --fmap::(a->b)->[a]->[b]
    fmap[]=[]
    fmap f(x:xs)=fx:fmap fxs
    
    请注意,实例是在类型构造函数上定义的,
    可能
    []
    ,而不是完全应用的类型
    可能是a
    [a]

    这不仅仅是一个客厅的把戏。它与参数多态性有很强的交互作用。由于类型
    fmap
    中的类型变量
    a
    b
    不受类定义的约束,因此
    Functor
    的实例无法基于它们更改其行为。在从类型推理代码时,这是一个非常强大的属性,Haskell的类型系统的强大之处就在于此

    它还有一个特性——您可以编写抽象类型更高的类型变量的代码。这里有几个例子:

    focusFirst::函子f=>(a->fb)->(a,c)->f(b,c)
    聚焦第一f(a,c)=fmap(\x->(x,c))(f a)
    聚焦秒::函子f=>(a->FB)->(c,a)->f(c,b)
    聚焦秒f(c,a)=fmap(\x->(c,x))(f a)
    
    我承认,这些类型开始看起来像抽象的废话。但当你有几个助手利用了更高级的抽象时,它们就变得非常实用了

    newtype Identity a=Identity{runIdentity::a}
    实例函子标识,其中
    --fmap::(a->b)->身份a->身份b
    fmap f(身份x)=身份(身份x)
    newtype Const c b=Const{getConst::c}
    实例函子(常量c),其中
    --fmap::(a->b)->常数c a->常数c b
    fmap u(常数c)=常数c
    设置::((a->Identity b)->s->Identity t)->b->s->t
    设置f b s=runIdentity(f(\\->Identity b)s)
    获取::((a->Const a b)->s->Const a t)->s->a
    get fs=getConst(f(\x->Const x)s)
    
    (如果我在那里犯了错误,有人能帮我修复吗?我正在从内存中重新实现
    lens
    的最基本起点,而无需编译器。)

    函数
    focusFirst
    focusSecond
    可以作为第一个参数传递给
    get
    set
    ,因为它们类型中的类型变量
    f
    可以与
    get
    set
    中更具体的类型统一。能够抽象更高级类型的变量
    f
    允许特定形状的函数在
    m :: (* -> *)
    
    * -> *
    
    class ClassExample<T, a> {
        T<a> function()
    }