gpt4 book ai didi

haskell - Haskell类型函数?

转载 作者:行者123 更新时间:2023-12-04 09:34:26 25 4
gpt4 key购买 nike

考虑以下ADT:

data Property f a = Property String (f a) | Zilch
deriving Show

什么是 f?它是作用于 a的函数吗?它是“类型函数”吗?讲师说Haskell有图灵完整的类型语言...所以我认为在这种情况下类型也可以具有功能?
*Main> var = Property "Colors" [1,2,3,4]
*Main> :t var
var :: Num a => Property [] a

此处的 f行为如何?由于 []是空列表的构造函数,因此 []是否始终是 f类型的最外面的空构造函数,如以下示例所示?
*Main> var = Property "Colors" [(1,"Red"),(2,"Blue")]
*Main> :t var
var :: Num t => Property [] (t, [Char])

*Main> var = Property "Colors" (1,"Red")
*Main> :t var
var :: Num t => Property ((,) t) [Char]

我不太了解后者,但是如果有人说Haskell推断出该元组的空构造函数,那么我可以购买。另一方面,
*Main> var = Property "Colors" 20
*Main> :t var
var :: Num (f a) => Property f a

这里的 a是什么?由于 f不能成为身份,但我们需要 id :: a -> a

我设法通过以下方法使ADT成为函子:
instance Functor f => Functor (Property f) where
fmap fun (Property name a) = Property name (fmap fun a)
fmap g Zilch = Zilch

所以像下面的作品
*Main> var = Property "Colors" [1,2,3,4]
*Main> fmap (+1) var
Property "Colors" [2,3,4,5]

但是,如果我将其提供给先前的元组示例,该怎么办?

我真的在寻找解释性的答案(在夏季 class 中,我只见过Haskell不到两个月的时间),而不是引用诸如 (f a)这样的东西来...说 FlexibleContexts可在任意 fmap上工作。

最佳答案

令人困惑的事实是,[]在Haskell中的不同上下文中具有两种不同的含义,这使您感到困惑,这使您难以解释其余的实验。

在值级别[]确实是列表的空构造函数。但是,当您询问Property "Colors" [1,2,3,4]的类型并看到Property [] a时,您正在查看的是类型表达式,而不是值表达式。在类型级别上没有空列表。1而是[]是列表类型的类型构造函数。您可以使用[Int](整数列表的类型),[Bool](布尔列表的类型)或[a](a列表的多态类型);在这些示例中,[]是应用于IntBoola的东西。

尽管看起来很奇怪,但实际上您可以根据需要将[Int]编写为[] Int,因此,当您不使用它时,通常只在类型级别看到[]

让我们再次看一下您的数据声明:

data Property f a = Property String (f a) | Zilch

在左侧,您已经声明了 的形状,类型为 PropertyProperty f a形成一个类型。在右侧,通过列出可能的值构造函数( PropertyZilch)以及这些构造函数中“槽”的类型(无 Zilch;一个槽的)来声明该类型的 的形状。类型 String和另一个类型 f a(对于 Property)。

因此,从中我们可以看出,无论 fa是什么,类型表达式 f a(应用于 fa)都必须形成具有值的类型。但是 f不一定非要(实际上也可以不是)正常的值类型! f值构造函数中没有 Property类型的插槽。

使用一个更清晰的示例是:
*Main> var = Property "Stuff" (Just True)
*Main> :t var
var :: Property Maybe Bool

如果您不知道, Maybe是一个内置类型,其声明如下所示:
data Maybe a = Just a | Nothing

对于本示例而言,这是有益的,因为我们在类型级别和值级别上没有使用相同的名称,这可以避免在您尝试了解事物的工作方式时造成混淆。
Just TrueMaybe Bool类型的值。在值级别,我们将 Just数据构造函数应用于值 True。在类型级别,我们将 Maybe类型构造函数应用于 Bool类型。 Maybe Bool值放入 f a值构造函数的 Property插槽中,该插槽很简单: fMaybeaBool

所以回到您的原始示例:
*Main> var = Property "Colors" [1,2,3,4]
*Main> :t var
var :: Num a => Property [] a

您正在使用 f a填充 [1, 2, 3, 4]插槽。那是某种数字的列表,所以它是 Num t => [t]。因此, a中的 f at(需要遵循 Num约束),而 f列表类型构造函数 []。此 []类似于 Maybe,而不是 Nothing
*Main> var = Property "Colors" (1,"Red")
*Main> :t var
var :: Num t => Property ((,) t) [Char]

此处 f a插槽中填充了 (1, "Red"),它是 Num t => (t, [Char])类型的(请记住 String只是编写 [Char]的另一种方式)。现在要了解这一点,我们必须有点挑剔。现在忘记约束,只关注 (t, [Char])。我们需要以某种方式将其解释为应用于其他对象,因此可以将其与 f a匹配。事实证明,尽管我们对元组类型有特殊的语法(例如 (a, b)),但它们实际上就像可以在不使用特殊语法的情况下声明的普通ADT一样。 2元组类型是一种类型构造函数,我们可以编写应用于其他两种类型的 (,),在这种情况下为 t[Char]。并且我们可以使用部分应用的类型构造函数,因此我们可以将应用于 (,)t视为一个单元,并将该单元应用于 [Char]。我们可以将该解释编写为Haskell类型表达式 ((,) t) [Char],但是我不确定是否更清楚。但是归结为,我们可以通过将第一个“单元” f a作为 (,) tf作为 [Char]将其与 a匹配。然后,这给了我们 Property ((,) t) [Char](只有我们还必须放回我们之前忘记的 Num t约束)。

最后是这个:
*Main> var = Property "Colors" 20
*Main> :t var
var :: Num (f a) => Property f a

在这里,我们用 f a(某种数字)填充 20插槽。我们尚未确切指定数字的类型,因此Haskell愿意相信它可以是 Num类中的任何类型。但是我们仍然需要该类型具有可以与 f a匹配的“形状”:将某种类型构造函数应用于其他某种类型。整个类型表达式 f a需要与 20的类型匹配,因此这就是 Num约束的条件。但是关于 fa可能是什么,我们没有说什么,而且 20可以满足 Num约束的任何类型,因此它可以是我们想要的任何 Num (f a) => f a,因此,为什么 var的类型仍然是多态的 fa(仅具有添加的约束)。

您可能只看到过 IntegerIntDouble等数字类型,所以想知道怎么可能会有一个 f a就是一个数字。所有这些示例只是单个基本类型,而不是应用于某些对象的类型。但是您可以编写自己的 Num实例,因此Haskell永远不会假设给定类型(或类型的形状)不能为数字,它只会抱怨您是否实际尝试使用它而找不到 Num实例。因此,有时您会得到类似这样的东西,它们可能是错误的,但是Haskell暂时接受 Num类型的代码,这是您没有想到的奇怪的事情。

实际上,内置库中已经有类型具有复合类型级别结构并具有 Num实例。一个示例是 Ratio类型,用于将小数表示为两个整数的比率。您可以使用 Ratio IntRatio Integer,例如:
Main*> 4 :: Ratio Int
4 % 1

所以你可以说:
*Main> var = Property "Colors" (20 :: Ratio Integer)
*Main> :t var
var :: Property Ratio Integer

1实际上,启用了 DataKinds扩展可以允许类型几乎反映任何值的结构,因此您可以拥有类型级别的列表。但这不是这里所发生的事情,它并不是真正可以使用的功能,除非您对香草Haskell中的类型和值的工作方式有了很好的了解,所以我建议您忽略此脚注并假装它不存在。

关于haskell - Haskell类型函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45202843/

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