Bergiの答えはちょうどいいです、多分私がお勧めしたい、他のものは末尾再帰アキュムレータはあなたの例ではiter
様ループ書かないで
test :: String -> Either String [Int]
test str = traverse parseNumber (words str)
parseNumber :: String -> Either String Int
parseNumber str
| all isDigit str = Right (read str)
| otherwise = Left (str ++ " is not a number")
:あなたはそれが簡単に提示し、この方法を理解するために見つけることができます。代わりに、ライブラリのドキュメントを見て、あなたが望むことをするリスト関数を見つけようとしてください。この場合、Bergiが正しく指摘したように、traverse
はあなたが望むものです。しかし、この機能に完全に慣れていくためには、いくらかの検討が必要です。しかしEither
のMonad
インスタンスとリストの仕事のTraversable
インスタンス、この例ではtraverse
は次のようにどのように機能するかを与えられた:
-- This is the same as `traverse` for lists and `Either`
traverseListWithEither :: (a -> Either err b) -> [a] -> Either err [b]
traverseListWithEither f [] = Right []
traverseListWithEither f (a:as) =
case f a of
Left err -> Left err
Right b -> mapEither (b:) (traverseListWithEither f as)
-- This is the same as the `fmap` function for `Either`
mapEither :: (a -> b) -> Either e a -> Either e b
mapEither f (Left e) = Left e
mapEither f (Right a) = Right (f a)
は、なぜあなたはreadEitherのための2つの引数をaplicate? @HaskellFun:1つのみ(String)引数を取る。 –
:ありがとう。私は何とかエラーメッセージと文字列を解析することを期待していました。 [驚異的なBifunctors](http://hackage.haskell.org/package/base-4.8.2.0/docs/Data-Bifunctor.html#v:first)を使用して今すぐ修正: – Bergi
それは私のようには機能しませんsoltuion。それは間違った文字列なしで解析エラーを返します –