如何正确设置函数的签名?
How I can set the signature of a function right?
我正在练习一些 Haskell 以更好地理解 \
、case.. of
和 Maybe
。
我这里有这个小函数,如果数组为空,return Nothing
,如果 y 等于数组 xs 的头部,Just y
Just (tail xs)
如果y不等于数组头部xs.
我将函数的 return 类型设置为 Maybe a
因为在一种情况下它应该 return 一个 Int
而在另一种情况下它应该是 [Int]
.
funct :: Int -> [Int] -> Maybe a
funct = \y xs -> case xs of
[] -> Nothing
xs -> if ((head xs) == y)
then Just y
else Just (tail xs)
我错过了什么?我得到的错误是它无法将类型 a
与 [Int]
匹配。 Maybe a
中的 a
不是通用的,还是受我 "used" a
作为 Just y
中的 Int
这一事实的影响部分?
编辑: 好的,我的建议是 bs,我在 then 和 else 部分用 Just (tail xs)
测试了它,但我仍然遇到同样的错误。
set the return type of the function to Maybe a
because in one case it should return an Int
and in the other an [Int]
.
Haskell 是 静态类型 。这意味着它不能 - 在运行时 - 具有不同的 return 类型。它只能有一个 return 类型。 a
不是 ad hoc 类型(在运行时它可以是任何类型的意义上)。这意味着 a
将在编译时根据其他参数的类型确定。
例如你可以写:foo :: a -> a -> a
指定如果 foo
需要两个 Int
s(在编译时再次已知),结果将是 Int
.
但是您可以使用 Either a b
表示您将 return Left a
或 Right b
。所以你可以改写为:
funct :: Int -> [Int] -> Maybe (Either Int [Int])
funct = \y xs -> case xs of
[] -> Nothing
xs -> if ((head xs) == y)
then Just (Left y)
else Just (Right (tail xs))
但是你的函数很冗长,你可以让它更清晰和紧凑,如下所示:
funct :: Int -> [Int] -> Maybe (Either Int [Int])
funct _ [] = Nothing
funct y (h:t) | h == y = Just (Left y)
| otherwise = Just (Right t)
此外,我们可以将其概括为:
funct :: Eq a => a -> [a] -> Maybe (Either a [a])
funct _ [] = Nothing
funct y (h:t) | h == y = Just (Left y)
| otherwise = Just (Right t)
这里Eq
是一个typeclass,指定存在一个我们可以使用的函数(==) :: a -> a -> Bool
。否则无法在函数体中使用 ==
。
此外,我们在每个子句的开头使用 patterns。 []
是描述 空列表 的模式。另一方面,(h:t)
是描述至少包含一个元素的列表的模式:头部 h
,后跟(可能是空尾部 t
)。
我正在练习一些 Haskell 以更好地理解 \
、case.. of
和 Maybe
。
我这里有这个小函数,如果数组为空,return Nothing
,如果 y 等于数组 xs 的头部,Just y
Just (tail xs)
如果y不等于数组头部xs.
我将函数的 return 类型设置为 Maybe a
因为在一种情况下它应该 return 一个 Int
而在另一种情况下它应该是 [Int]
.
funct :: Int -> [Int] -> Maybe a
funct = \y xs -> case xs of
[] -> Nothing
xs -> if ((head xs) == y)
then Just y
else Just (tail xs)
我错过了什么?我得到的错误是它无法将类型 a
与 [Int]
匹配。 Maybe a
中的 a
不是通用的,还是受我 "used" a
作为 Just y
中的 Int
这一事实的影响部分?
编辑: 好的,我的建议是 bs,我在 then 和 else 部分用 Just (tail xs)
测试了它,但我仍然遇到同样的错误。
set the return type of the function to
Maybe a
because in one case it should return anInt
and in the other an[Int]
.
Haskell 是 静态类型 。这意味着它不能 - 在运行时 - 具有不同的 return 类型。它只能有一个 return 类型。 a
不是 ad hoc 类型(在运行时它可以是任何类型的意义上)。这意味着 a
将在编译时根据其他参数的类型确定。
例如你可以写:foo :: a -> a -> a
指定如果 foo
需要两个 Int
s(在编译时再次已知),结果将是 Int
.
但是您可以使用 Either a b
表示您将 return Left a
或 Right b
。所以你可以改写为:
funct :: Int -> [Int] -> Maybe (Either Int [Int])
funct = \y xs -> case xs of
[] -> Nothing
xs -> if ((head xs) == y)
then Just (Left y)
else Just (Right (tail xs))
但是你的函数很冗长,你可以让它更清晰和紧凑,如下所示:
funct :: Int -> [Int] -> Maybe (Either Int [Int])
funct _ [] = Nothing
funct y (h:t) | h == y = Just (Left y)
| otherwise = Just (Right t)
此外,我们可以将其概括为:
funct :: Eq a => a -> [a] -> Maybe (Either a [a])
funct _ [] = Nothing
funct y (h:t) | h == y = Just (Left y)
| otherwise = Just (Right t)
这里Eq
是一个typeclass,指定存在一个我们可以使用的函数(==) :: a -> a -> Bool
。否则无法在函数体中使用 ==
。
此外,我们在每个子句的开头使用 patterns。 []
是描述 空列表 的模式。另一方面,(h:t)
是描述至少包含一个元素的列表的模式:头部 h
,后跟(可能是空尾部 t
)。