好像你感到困惑类型变量。首先,在
f :: Maybe a -> Maybe a
f = \a -> a
的a
的第一行无关与a
“在第二行S,我们可以这样写:
f :: Maybe a -> Maybe a
f = \x -> x
甚至
f :: Maybe foo -> Maybe foo
f = \bar -> bar
a
是代表类型的变量。所以f
这里宣布f
有一次一大堆类型:
f :: Maybe Int -> Maybe Int
f :: Maybe String -> Maybe String
f :: Maybe (Maybe Bool) -> Maybe (Maybe Bool)
...
等。这不是我怀疑你认为的一些“标签”的论点。两个a
都相同的事实意味着参数类型必须是相同的结果类型。如果我们说f :: Maybe a -> Maybe b
我们会得到这个家庭:
f :: Maybe Int -> Maybe Bool
f :: Maybe String -> Maybe String
f :: Maybe (Maybe Bool) -> Maybe Int
...
也就是a
和b
现在可以代表不同的类型,但参数和结果还是要Maybe
。
的原因,你不能说
f :: Maybe -> Maybe
是因为Maybe
不是一个类型 - 这是一个类型构造。如果你给它一个类型,它会给你一个类型。所以Maybe Int
和Maybe String
是类型,一般Maybe a
是一种类型,只要a
是一种类型。
Maybe Int a
(这是解析(Maybe Int) a
)没有意义,因为Maybe Int
不是一个类型的构造函数 - 它不接受任何更多的参数。
建议阅读:Types and Typeclasses来自LYAH。
您似乎对类型签名中“a”代表的含义感到困惑。 '也许'不是一个类型,它是*类型的构造函数*。你提供一个类型,你得到一个新的类型,比如'Maybe Int','Maybe Bool','Maybe [String]'或Maybe(Maybe Char)'。 '也许'本身不是一个有效的类型,所以'也许 - >也许'也不是一个有效的类型。 'a'是一个*类型的变量*,它代表了一些调用者提供的类型,所以'也许a - >也许a''意味着'a'可以是任何类型,只要它在两边都是相同的。 'a'与你的lambda中的'a'没有关系,它完全位于另一个命名空间中。 –
由于没有人提到它,所以'Int 5'只有在'Int'是一个构造函数时(如'Just','Left')才有效,但它不是。如果你想说'5'是'Int'类型,你可以使用类型注解('5 :: Int'),但在这种情况下它不是必需的。 – SwiftsNamesake