Haskell - 可能和递归
Haskell - Maybe and Recursion
我想把一个字符串变成一个Direction
的列表。例如,"UDDUD"
应该 return [U,D,D,U,D]
,而任何不包含 U
或 D
return 的字符串 Nothing
(例如 "UDYD" returns Nothing
)。
data Direction = U | D
deriving (Show, Eq)
-- where U is Up and D is Down
findDirection :: [Char] -> Maybe [Direction]
findDirection [] = Nothing
findDirection ['U'] = Just [U]
findDirection ['D'] = Just [D]
findDirection (x:xs)
| x == 'U' = Just (U : findDirection xs)
| x == 'D' = Just (D : findDirection xs)
| otherwise = Nothing
我收到以下错误:
Couldn't match expected type ‘[Direction]’
with actual type ‘Maybe [Direction]’
In the second argument of ‘(:)’, namely ‘findDirection xs’
In the first argument of ‘Just’, namely
‘(U : findDirection xs)’
Test_findDirection.hs:8:32:
Couldn't match expected type ‘[Direction]’
with actual type ‘Maybe [Direction]’
In the second argument of ‘(:)’, namely ‘findDirection xs’
In the first argument of ‘Just’, namely
‘(D : findDirection xs)’
据我了解,Just (D : findDirection xs)
和Just (U : findDirection xs)
是[Direction]
类型的?为什么会这样?我在这里做错了什么?
Just (D : findDirection xs)
and Just (U : findDirection xs)
are of type [Direction]? Why is this the case? What am I doing wrong, here?
不,Just (D : findDirection xs)
实际上是错误类型。让我们剖析此错误消息:
Couldn't match expected type ‘[Direction]’
with actual type ‘Maybe [Direction]’
我们在实际应该使用 [Direction]
的地方使用 Maybe [Direction]
。
In the second argument of ‘(:)’, namely ‘findDirection xs’
啊哈。我们使用 (:) :: a -> [a] -> [a]
错误。毕竟,findDirection
将 return 变成 Maybe [Direction]
,而不是 [Direction]
。我们需要这样的东西:
consOnMaybe :: a -> Maybe [a] -> Maybe [a]
consOnMaybe _ Nothing = Nothing
consOnMaybe x (Just xs) = Just (x : xs)
现在你的函数可以写成
findDirection (x:xs)
| x == 'U' = consOnMaybe U (findDirection xs)
| x == 'D' = consOnMaybe D (findDirection xs)
| otherwise = Nothing
或者,我们可以使用 consOnMaybe x = fmap (x:)
。作为额外的奖励,这里有一个使用预定义函数且没有显式递归的变体(练习:了解它是如何工作的)
findDirection :: [Char] -> Maybe [Direction]
findDirection [] = Nothing
findDirection xs = traverse toDirection xs
toDirection :: Char -> Maybe Direction
toDirection 'U' = Just U
toDirection 'D' = Just D
toDirection _ = Nothing
data Direction = U | D
deriving (Show, Eq)
findDirection :: String -> Maybe [Direction]
findDirection [] = Nothing
findDirection dirs = sequence $ findDirection' dirs
where
findDirection' :: String -> [Maybe Direction]
findDirection' (x:xs) =
let x' = toDirection x in
x' : case x' of
Just _ -> findDirection' xs
_ -> []
findDirection' _ = []
toDirection :: Char -> Maybe Direction
toDirection 'U' = Just U
toDirection 'D' = Just D
toDirection _ = Nothing
------------------------ OR ------------------------
findDirection :: String -> Maybe [Direction]
findDirection [] = Nothing
findDirection dirs = traverse toDirection dirs
where
toDirection :: Char -> Maybe Direction
toDirection 'U' = Just U
toDirection 'D' = Just D
toDirection _ = Nothing
> findDirection "UDDUD"
< Just [U,D,D,U,D]
> findDirection "UDYD"
< Nothing
我想把一个字符串变成一个Direction
的列表。例如,"UDDUD"
应该 return [U,D,D,U,D]
,而任何不包含 U
或 D
return 的字符串 Nothing
(例如 "UDYD" returns Nothing
)。
data Direction = U | D
deriving (Show, Eq)
-- where U is Up and D is Down
findDirection :: [Char] -> Maybe [Direction]
findDirection [] = Nothing
findDirection ['U'] = Just [U]
findDirection ['D'] = Just [D]
findDirection (x:xs)
| x == 'U' = Just (U : findDirection xs)
| x == 'D' = Just (D : findDirection xs)
| otherwise = Nothing
我收到以下错误:
Couldn't match expected type ‘[Direction]’
with actual type ‘Maybe [Direction]’
In the second argument of ‘(:)’, namely ‘findDirection xs’
In the first argument of ‘Just’, namely
‘(U : findDirection xs)’
Test_findDirection.hs:8:32:
Couldn't match expected type ‘[Direction]’
with actual type ‘Maybe [Direction]’
In the second argument of ‘(:)’, namely ‘findDirection xs’
In the first argument of ‘Just’, namely
‘(D : findDirection xs)’
据我了解,Just (D : findDirection xs)
和Just (U : findDirection xs)
是[Direction]
类型的?为什么会这样?我在这里做错了什么?
Just (D : findDirection xs)
andJust (U : findDirection xs)
are of type [Direction]? Why is this the case? What am I doing wrong, here?
不,Just (D : findDirection xs)
实际上是错误类型。让我们剖析此错误消息:
Couldn't match expected type ‘[Direction]’
with actual type ‘Maybe [Direction]’
我们在实际应该使用 [Direction]
的地方使用 Maybe [Direction]
。
In the second argument of ‘(:)’, namely ‘findDirection xs’
啊哈。我们使用 (:) :: a -> [a] -> [a]
错误。毕竟,findDirection
将 return 变成 Maybe [Direction]
,而不是 [Direction]
。我们需要这样的东西:
consOnMaybe :: a -> Maybe [a] -> Maybe [a]
consOnMaybe _ Nothing = Nothing
consOnMaybe x (Just xs) = Just (x : xs)
现在你的函数可以写成
findDirection (x:xs)
| x == 'U' = consOnMaybe U (findDirection xs)
| x == 'D' = consOnMaybe D (findDirection xs)
| otherwise = Nothing
或者,我们可以使用 consOnMaybe x = fmap (x:)
。作为额外的奖励,这里有一个使用预定义函数且没有显式递归的变体(练习:了解它是如何工作的)
findDirection :: [Char] -> Maybe [Direction]
findDirection [] = Nothing
findDirection xs = traverse toDirection xs
toDirection :: Char -> Maybe Direction
toDirection 'U' = Just U
toDirection 'D' = Just D
toDirection _ = Nothing
data Direction = U | D
deriving (Show, Eq)
findDirection :: String -> Maybe [Direction]
findDirection [] = Nothing
findDirection dirs = sequence $ findDirection' dirs
where
findDirection' :: String -> [Maybe Direction]
findDirection' (x:xs) =
let x' = toDirection x in
x' : case x' of
Just _ -> findDirection' xs
_ -> []
findDirection' _ = []
toDirection :: Char -> Maybe Direction
toDirection 'U' = Just U
toDirection 'D' = Just D
toDirection _ = Nothing
------------------------ OR ------------------------
findDirection :: String -> Maybe [Direction]
findDirection [] = Nothing
findDirection dirs = traverse toDirection dirs
where
toDirection :: Char -> Maybe Direction
toDirection 'U' = Just U
toDirection 'D' = Just D
toDirection _ = Nothing
> findDirection "UDDUD"
< Just [U,D,D,U,D]
> findDirection "UDYD"
< Nothing