鉴于以下计划,我遇到了与monad打交道的问题.
module Main
where
import System.Environment
import System.Directory
import System.IO
import Text.CSV
--------------------------------------------------
exister :: String -> IO Bool
exister path = do
fileexist <- doesFileExist path
direxist <- doesDirectoryExist path
return (fileexist || direxist )
--------------------------------------------------
slurp :: String -> IO String
slurp path = do
withFile path ReadMode (\handle -> do
contents <- hGetContents handle
last contents `seq` return contents )
--------------------------------------------------
main :: IO ()
main = do
[csv_filename] <- getArgs
putStrLn (show csv_filename)
csv_raw <- slurp csv_filename
let csv_data = parseCSV csv_filename csv_raw
printCSV csv_data -- unable to compile.
Run Code Online (Sandbox Code Playgroud)
csv_data是一种Either(parseerror)CSV类型,而printCSV只接受CSV数据.
这是工作版和破碎版之间的编辑.
***************
*** 27,30 ****
csv_raw <- slurp csv_filename
let csv_data = parseCSV csv_filename csv_raw
! printCSV csv_data -- unable to compile.
\ No newline at end of file
--- 27,35 ----
csv_raw <- slurp csv_filename
let csv_data = parseCSV csv_filename csv_raw
! case csv_data of
! Left error -> putStrLn $ show error
! Right csv_data -> putStrLn $ printCSV csv_data
!
! putStrLn "done"
!
Run Code Online (Sandbox Code Playgroud)
参考:http://hackage.haskell.org/packages/archive/csv/0.1.2/doc/html/Text-CSV.html
Dan*_*ton 10
关于monads:
是的,Either a
是一个单子.所以简化问题,你基本上要求这个:
main = print $ magicMonadUnwrap v
v :: Either String Int
v = Right 3
magicMonadUnwrap :: (Monad m) => m a -> a
magicMonadUnwrap = undefined
Run Code Online (Sandbox Code Playgroud)
你怎么定义magicMonadUnwrap
?嗯,你看,每个monad都不一样.每个人都需要自己的解包装.许多这些有字"跑"在其中,例如runST
,runCont
或runEval
.但是,对于某些monad来说,打开它们可能并不安全(因此需要不同的unwrappers).
列表的一个实现是head
.但是如果列表是空的怎么办?一个unwrapper for Maybe
is fromJust
,但如果它是Nothing
什么?
同样,Either
monad的unwrapper将是这样的:
fromRight :: Either a b -> b
fromRight (Right x) = x
Run Code Online (Sandbox Code Playgroud)
但是这个解包器并不安全:如果你有一个Left
价值怎么办?(左侧通常表示错误状态,在您的情况下,是一个解析错误).所以最好的办法时的行动Either
值是使用either
功能,或者使用一个case语句匹配Right
和Left
,丹尼尔·瓦格纳所示.
tl;博士:没有magicMonadUnwrap
.如果你在同一个monad中,你可以使用<-
,但要真正从monad中提取价值......好吧......你怎么做取决于你正在处理的monad.
使用case
.
main = do
...
case csv_data of
Left err -> {- whatever you're going to do with an error -- print it, throw it as an exception, etc. -}
Right csv -> printCSV csv
Run Code Online (Sandbox Code Playgroud)
该either
功能是短(语法明智),但归结为同样的事情.
main = do
...
either ({- error condition function -}) printCSV csv_data
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3843 次 |
最近记录: |