2016-04-09 6 views
2

私は文字列を取ってDirectionのリストにしたいと思います。たとえば、"UDDUD"[U,D,D,U,D]を返し、UまたはDを含まない文字列はNothingを返します(たとえば、「UDYD」は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]のですか。これはなぜですか?私は何を間違えているのですか?

+1

'U:findirectionのxs'(と' D:findDirection xs' )はタイプミスです:あなたは 'Direction'を'たぶん[Direction] 'に賛成できません。また、あなたは次のように書いています:* [...] 'U'や' D'を含まない文字列は 'Nothing'を返します(例えば' 'UDYD''は' Nothing'を返します)。*あなたは自分自身と矛盾していませんか? ? – Jubobs

答えて

5

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)は実際にはタイプミスです。のは、このエラーメッセージを分析してみましょう:私たちは実際に[Direction]を使用する必要がある時点でMaybe [Direction]を使用している

Couldn't match expected type ‘[Direction]’ 
       with actual type ‘Maybe [Direction]’ 

In the second argument of ‘(:)’, namely ‘findDirection xs’ 

Aha。我々は(:) :: a -> [a] -> [a]が間違っています。結局、findDirectionはではなくMaybe [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 
0
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 
関連する問題