是否可以为此getConstructor
函数提供类型签名?
该函数有效,但是我找不到写返回类型的方法。
module Main where
data Letter a =
A a
| B a
| C String
deriving (Show)
-- getConstructor :: String -> (a -> Letter ?) -- <==
getConstructor x
| x == "a" = A
| x == "b" = B
| otherwise = C
main = print $ theType
where theType = (getConstructor "b") "its b!"
主要印刷品B "its b!"
答案 0 :(得分:4)
让我们看看:
getConstructor x
| x == "a" = A
| x == "b" = B
| otherwise = C -- <= Let's inspect this line
该行返回C :: String -> Letter a
。前一行返回B :: a -> Letter a
。这些类型必须相等,因此a ~ String
。因此,该函数变为:
getConstructor :: String -> (String -> Letter String)
无法使用类似这样的函数在运行时动态选择类型,因为在Haskell中,所有类型在编译时都是已知的。因此,仅限于String
上使用。
答案 1 :(得分:3)
我只是将您的代码输入到GHCi中,并要求它告诉我类型:
Prelude> :{
Prelude| data Letter a =
Prelude| A a
Prelude| | B a
Prelude| | C String
Prelude| deriving (Show)
Prelude| :}
Prelude> :{
Prelude| getConstructor x
Prelude| | x == "a" = A
Prelude| | x == "b" = B
Prelude| | otherwise = C
Prelude| :}
Prelude> :t getConstructor
getConstructor :: [Char] -> String -> Letter String
这很有意义,因为它需要一个[Char]
(又名String
-即x
参数)并返回A
,B
和C
,它们是Letter
的构造函数。作为构造函数,它们也是函数-在C
的情况下,类型显然是String -> Letter a
,而A
和B
的类型为a -> Letter a
。由于这些都是getConstructor
的可能返回值,因此它们必须是同一类型-发生这种情况的唯一方法是,如果a
始终为String
。这使我们将getConstructor
的类型设为String -> (String -> Letter String)
,这正是GHCi上面所说的(稍有重写)。