我有一个代数数据类型,如:
data Toll = Vok Int Bool | Bok Int | Cokd String Char
和另一个功能
getVal :: Int -> Toll
getVal 1 = Cokd "hello" 'c'
getVal _ = Bok 12
我想在某个函数中调用getVal
并提取Cokd
的参数(如果答案类型为Cokd
)(可能使用模式匹配)。
hello :: Int -> Bool
hello x = if st == "hell" then True else False
where (Cokd st ch) = getVal x
我不能使用monad。
怎么做?
答案 0 :(得分:5)
您可以使用case
模式匹配getVal
的结果:
data Toll = Vok Int Bool | Bok Int | Cokd String Char
getVal :: Int -> Toll
getVal 1 = Cokd "hello" 'c'
getVal _ = Bok 12
hello :: Int -> Bool
hello x =
case getVal x of
Cokd st ch ->
st == "hell"
_ -> False
或创建一个单独的函数和模式匹配参数:
hello :: Int -> Bool
hello =
helloToll . getVal
where
helloToll (Cokd st ch) = st == "hell"
helloToll _ = False
您在问题中提供的示例(编译很少),但当您尝试使用hello
(或任何其他值不同)调用2
时,它会抛出运行时异常来自1
,在这种情况下,getValue
会返回Bok 12
,因此(Cokd st ch) = getVal x
无法进行模式匹配。
答案 1 :(得分:3)
您的代码似乎完全正常,只需进行一次更正:模式if <expr> then True else False
可以替换为<expr>
。
hello :: Int -> Bool
hello x = st == "hell" where (Cokd st ch) = getVal x
但是,由于非详尽的模式匹配,此代码将因1
以外的值而失败。您需要涵盖所有情况:
hello :: Int -> Bool
hello x = case getVal x of
Cokd st ch -> st == "hell"
_ -> False