来自tuple-Haskell的函数

来自tuple-Haskell的函数,haskell,pattern-matching,Haskell,Pattern Matching,对于那些擅长Haskell的人来说,这是一个简单的问题! 为什么我要写: let a b = (5,6) 我得到一个函数: a :: p -> (a, b) 此外,b没有实例化。我试图理解它,但徒劳。 谢谢你的帮助 let a b = (5, 6) 您正在定义一个名为a的函数,它接受一个名为b的参数。此函数忽略其参数并返回5,6。我假设您希望a和b分别绑定到5和6,在这种情况下,您需要以下语法 let (a, b) = (5, 6) 您正在定义一个名为a的函数,它接受一个名为b的参

对于那些擅长Haskell的人来说,这是一个简单的问题! 为什么我要写:

let a b = (5,6)
我得到一个函数:

a :: p -> (a, b)
此外,b没有实例化。我试图理解它,但徒劳。 谢谢你的帮助

let a b = (5, 6)
您正在定义一个名为a的函数,它接受一个名为b的参数。此函数忽略其参数并返回5,6。我假设您希望a和b分别绑定到5和6,在这种情况下,您需要以下语法

let (a, b) = (5, 6)
您正在定义一个名为a的函数,它接受一个名为b的参数。此函数忽略其参数并返回5,6。我假设您希望a和b分别绑定到5和6,在这种情况下,您需要以下语法

let (a, b) = (5, 6)

关于Haskell为什么会得出具体结果的答案更为详细:

好的,让我们把它分解一下。在Haskell中,数值常量可以有多个可能的类型,因此5可以是Int、Integer、Word等,而5,6可能有Int、Integer、Int、Int等类型。因此,GHC任意地将其类型表示为a,b,并将等待,看看您稍后是否在上下文中使用该结果,以便它推断该类型。如果不是,则默认为整数、整数

碰巧GHC为未知类型分配了相同的小写字母,这些未知类型在等号左侧用作标识符,但它们是相同名称的不相关用法。你可以将a b=改为f_=5,6,如果这能让你更清楚地了解Haskell从字面上理解的内容

声明AB是一个名为a的函数,有一个参数b。此参数未使用,因此GHC无法推断其类型,除非您调用它,并且它将其指定为p

所以您声明了一个函数,它接受一个p并返回一对未知类型a和b的数字:p->a,b

正如Sivio Mayolo击败我说的,如果你想绑定变量a和b,你可以写a,b=5,6

附笔。: HTNW建议我多谈一点数字类型可以具有的值。表示:“整型文字表示函数fromInteger应用于integer类型的适当值。”

因此,常数5相当于fromInteger 5::Integer

fromInteger定义在哪里?作为typeclass Num的一部分。它的类型为fromInteger::Num a=>Integer->a。也就是说,typeclass Num的每个实例(包括Int、Double等)都有自己定义的fromInteger多态版本,它将整数转换为该类型的值

如果编译器可以推断常量的类型,或者因为您提供了类型注释,或者因为您在需要特定类型的表达式中使用它,那么它将知道调用哪个版本的fromInteger来获取该类型的常量。事实上,它肯定会在编译时优化调用,并在运行时使用结果。如果完全由编译器决定,GHC将选择整数并向您发出警告

如果您尝试绑定x=5,然后使用x作为任何类型的Num,它都会工作,但是如果您尝试将其作为两种不同的类型使用,编译器将无法解析它。因此,如果您需要在一行中使用x作为Int,然后希望稍后将其作为Double传递,那么您需要将转换写入Double作为from integral x。这样一来,x一直都是整数,每个人都很高兴

一个可能但类型系统不允许的转换示例:与C不同,尝试将数字文字用作字符将不起作用,因为Char不是Num的实例。但是,它是一个枚举,因此可以使用fromEnum和toEnum在Char和Int之间进行转换

因此,如果您在GHCI中尝试此操作,您会得到:

Prelude> 7 :: Char

<interactive>:1:1: error:
    • No instance for (Num Char) arising from the literal ‘7’
    • In the expression: 7 :: Char
      In an equation for ‘it’: it = 7 :: Char

这实际上是整型7::Char中的toEnum。每个枚举都有一个toEnum函数,该函数将Int转换为该类型的枚举。末尾的::Char告诉GHCI要转换为的枚举是Char,因此GHCI可以推断它应该将7从Integer转换为Int再转换为Char。Haskell从C借用了ASCII/Unicode代码点7的“\a”转义码。为了提醒,如果你在终端上键入control-G,它会向你发出嘟嘟声。它可能仍然可以在Linux控制台中工作,或者至少使窗口闪烁。

关于Haskell为什么会产生特定结果的详细答案如下:

好的,让我们把它分解一下。在Haskell中,数值常量可以有多个可能的类型,因此5可以是Int、Integer、Word等,而5,6可能有Int、Integer、Int、Int等类型。因此,GHC任意地将其类型表示为a,b,并将等待,看看您稍后是否在上下文中使用该结果,以便它推断该类型。如果不是,则默认为整数、整数

碰巧GHC为未知类型分配了相同的小写字母,这些未知类型在等号左侧用作标识符,但它们是相同名称的不相关用法。如果可以的话,你可以把a b=改成f=5,6 从字面上看,哈斯克尔看到的更清楚

声明AB是一个名为a的函数,有一个参数b。此参数未使用,因此GHC无法推断其类型,除非您调用它,并且它将其指定为p

所以您声明了一个函数,它接受一个p并返回一对未知类型a和b的数字:p->a,b

正如Sivio Mayolo击败我说的,如果你想绑定变量a和b,你可以写a,b=5,6

附笔。: HTNW建议我多谈一点数字类型可以具有的值。表示:“整型文字表示函数fromInteger应用于integer类型的适当值。”

因此,常数5相当于fromInteger 5::Integer

fromInteger定义在哪里?作为typeclass Num的一部分。它的类型为fromInteger::Num a=>Integer->a。也就是说,typeclass Num的每个实例(包括Int、Double等)都有自己定义的fromInteger多态版本,它将整数转换为该类型的值

如果编译器可以推断常量的类型,或者因为您提供了类型注释,或者因为您在需要特定类型的表达式中使用它,那么它将知道调用哪个版本的fromInteger来获取该类型的常量。事实上,它肯定会在编译时优化调用,并在运行时使用结果。如果完全由编译器决定,GHC将选择整数并向您发出警告

如果您尝试绑定x=5,然后使用x作为任何类型的Num,它都会工作,但是如果您尝试将其作为两种不同的类型使用,编译器将无法解析它。因此,如果您需要在一行中使用x作为Int,然后希望稍后将其作为Double传递,那么您需要将转换写入Double作为from integral x。这样一来,x一直都是整数,每个人都很高兴

一个可能但类型系统不允许的转换示例:与C不同,尝试将数字文字用作字符将不起作用,因为Char不是Num的实例。但是,它是一个枚举,因此可以使用fromEnum和toEnum在Char和Int之间进行转换

因此,如果您在GHCI中尝试此操作,您会得到:

Prelude> 7 :: Char

<interactive>:1:1: error:
    • No instance for (Num Char) arising from the literal ‘7’
    • In the expression: 7 :: Char
      In an equation for ‘it’: it = 7 :: Char

这实际上是整型7::Char中的toEnum。每个枚举都有一个toEnum函数,该函数将Int转换为该类型的枚举。末尾的::Char告诉GHCI要转换为的枚举是Char,因此GHCI可以推断它应该将7从Integer转换为Int再转换为Char。Haskell从C借用了ASCII/Unicode代码点7的“\a”转义码。为了提醒,如果你在终端上键入control-G,它会向你发出嘟嘟声。它可能仍然在Linux控制台中工作,或者至少使窗口闪烁。

您可能需要指出,数字文本不能有任何类型,但它们实际上是用于所有类型的。Num a=>a,也许可以解释fromInteger是如何实现这一点的。这是Haskell程序员在某个时候肯定会想了解的主题,但对于这个问题来说,可能离正切有点太远了?这是非常正确的,为什么我说“不止一种类型”,而不是任何类型。我要说的是,理解数字是如何多态的很重要。您已经解释了类型是如何工作的,但是您没有说明值的实际情况,我认为这在问题的范围之内。由你决定。好的,我在最后添加了一个讨论,因为是你要求的。在回答一个关于如何编写一对的新手问题时,把它放在这里有点矛盾。你可能想提到数字文字不能有任何类型,但它们实际上都是a。Num a=>a,也许可以解释fromInteger是如何实现这一点的。这是Haskell程序员在某个时候肯定会想了解的主题,但对于这个问题来说,可能离正切有点太远了?这是非常正确的,为什么我说“不止一种类型”,而不是任何类型。我要说的是,理解数字是如何多态的很重要。您已经解释了类型是如何工作的,但是您没有说明值的实际情况,我认为这在问题的范围之内。由你决定。好的,我在最后添加了一个讨论,因为是你要求的。在回答一个新手关于如何写一对的问题时,把它放在这里有点矛盾。