haskell类型signatur用于返回类型构造函数

时间:2019-04-20 11:58:15

标签: haskell types constructor return-type

是否可以为此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!"

2 个答案:

答案 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参数)并返回ABC,它们是Letter的构造函数。作为构造函数,它们也是函数-在C的情况下,类型显然是String -> Letter a,而AB的类型为a -> Letter a。由于这些都是getConstructor的可能返回值,因此它们必须是同一类型-发生这种情况的唯一方法是,如果a始终为String。这使我们将getConstructor的类型设为String -> (String -> Letter String),这正是GHCi上面所说的(稍有重写)。