使用try将String转换为Float
我尝试解析一个文件。它是一个 3d 点列表。我编写了这个函数来提取一行的第一个和第二个数字。现在我想检查从 String 到 Float(read function) 的转换是否成功。如果转换成功,我想返回 Point(Just Point2D),而在尝试失败时返回 Nothing。问题是这个案例想要一个 IO 但得到一个简单的。代码是从这篇文章中抽象出来的:Haskell 中的异常处理
-- | reads out of a splitted line the first and second of the list and returns a list of Points2D
pointExtraction
:: [String]
-> Maybe Point2D
pointExtraction (x:y:tail) = do
let result = try ( evaluate (createPoint x y )) :: IO (Either SomeException Point2D)
case result of
Left ex -> Nothing
Right point -> (Just point)
createPoint :: String -> String -> Point2D
createPoint x y = Point2D (read x) (read y)
-- | reads out of a splitted line the first and second of the list and returns a list of Points2D
pointExtraction
:: [String]
-> Maybe Point2D
pointExtraction (x:y:tail) = do
let result = try ( evaluate (createPoint x y )) :: IO (Either SomeException Point2D)
case result of
Left ex -> Nothing
Right point -> (Just point)
createPoint :: String -> String -> Point2D
createPoint x y = Point2D (read x) (read y)
例外:
回答
许多与异常相关的函数像try和evaluate都被限制IO在 Haskell 中。您可以重构代码以在以下环境中工作IO:
-- | reads out of a splitted line the first and second of the list and returns a list of Points2D
pointExtraction
:: [String]
-> IO (Maybe Point2D)
pointExtraction (x:y:tail) = do
result <- try ( evaluate (createPoint x y )) :: IO (Either SomeException Point2D)
case result of
Left ex -> pure Nothing
Right point -> pure (Just point)
createPoint :: String -> String -> Point2D
createPoint x y = Point2D (read x) (read y)
但这并不理想,因为现在您也只能pointExtraction在IO. 这就是IO基本的工作原理:它总是强制使用它的地方也使用IO.
防止这种情况的方法是避免使用异常。相反,您可以使用MaybeorEither类型作为返回类型。有一个版本read叫做readMaybe中Text.Read模块。您可以使用它来避免IO:
import Text.Read (readMaybe)
-- | reads out of a splitted line the first and second of the list and returns a list of Points2D
pointExtraction
:: [String]
-> Maybe Point2D
pointExtraction (x:y:tail) = createPoint x y
createPoint :: String -> String -> Maybe Point2D
createPoint strX strY = do
x <- readMaybe strX
y <- readMaybe strY
pure (Point2D x y)