如何在递归函数中返回不同的类型? (哈斯克尔)

时间:2018-10-15 06:10:45

标签: haskell recursion types return-type

我需要在递归函数中返回例如整数或布尔值。

我的问题的示例代码:

findInt :: [Int] -> Either Int Bool
findInt (x:xs) =
     if x == 1 then x
     else False : findInt xs

然后错误提示无法将预期的类型“ Either Int Bool”与实际类型“ Int” 匹配。但是我想检查该元素是否在此列表中,如果存在,它将返回该元素,并通过返回布尔值告诉我是否不在该元素中。

3 个答案:

答案 0 :(得分:4)

如果您查看Either类型,您会看到它具有两个构造函数LeftRight。为了构造Either类型的值,您需要使用其中一个构造函数。例如

if x == 1 then Left x

具体来说,Left用于构造两种类型的第一种类型(在这种情况下为Int),Right用于第二种类型(Bool在这种情况下)。

答案 1 :(得分:3)

给定的函数没有类型:x :: Int(False : _) :: [Bool],并且这两种类型无法统一(将::读为“具有类型”)。

已调整

findInt (x:xs) =
     if x == 1 then Left x
     else Right False : findInt xs

它仍然没有类型:Left x :: Either Int b(Right False : _) :: [Either a Bool],并且这两种类型也无法统一。

但是

findInt :: [Int] -> Either Int Bool
findInt (x:xs) =
     if x == 1 then Left x
     else findInt xs
findInt [] = Right False

具有一种类型,因为Left x :: Either Int bRight False :: Either a Bool以及这两种类型 可以统一:

        Either Int b
        Either a   Bool
       -----------------      a ~ Int , b ~ Bool
        Either Int Bool

统一签名确实是Either Int Bool,如类型签名所指定。

答案 2 :(得分:1)

由于您从未在输出中使用True,因此Either Int Bool的使用与Maybe Int是同构的:

a2b :: Either Int Bool -> Maybe Int
a2b (Right x) = Just x
a2b (Left x) = Nothing

b2a :: Maybe Int -> Either Int Bool
b2a (Just x) -> Right x
b2a Nothing -> Left False

这样,我只用Maybe Int来简化您的功能。

findInt :: [Int] -> Maybe Int
findInt [] = Nothing
findInt (x:xs) = if x == 1 then Just x else findInt xs