gpt4 book ai didi

haskell - 展开一个单子(monad)

转载 作者:行者123 更新时间:2023-12-03 14:42:49 27 4
gpt4 key购买 nike

鉴于以下程序,我在处理单子(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.

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"
!

引用: http://hackage.haskell.org/packages/archive/csv/0.1.2/doc/html/Text-CSV.html

最佳答案

关于单子(monad):

是的,Either a是一个单子(monad)。所以简化问题,你基本上要求这个:

main = print $ magicMonadUnwrap v

v :: Either String Int
v = Right 3

magicMonadUnwrap :: (Monad m) => m a -> a
magicMonadUnwrap = undefined

你如何定义 magicMonadUnwrap ?嗯,你看,每个单子(monad)都是不同的。每个人都需要自己的解包器。其中许多都有“运行”一词,例如, runST , runCont , 或 runEval .但是,对于某些 monad,展开它们可能不安全(因此需要不同的展开器)。

列表的一种实现是 head .但是如果列表为空怎么办? Maybe 的解包器是 fromJust , 但如果是 Nothing ?

同样, Either 的解包器monad 会是这样的:
fromRight :: Either a b -> b
fromRight (Right x) = x

但是这个解包器并不安全:如果你有一个 Left 怎么办?取而代之的是值(value)? (左通常代表错误状态,在您的情况下,是解析错误)。因此,对 Either 采取行动的最佳方式使用 either 的值(value)函数,或者使用匹配 Right 的 case 语句和 Left ,正如丹尼尔瓦格纳所说明的那样。

tl;博士 : 没有 magicMonadUnwrap .如果你在同一个单子(monad)里,你可以使用 <- ,但是要真正从单子(monad)中提取值(value)……嗯……你怎么做取决于你正在处理的单子(monad)。

关于haskell - 展开一个单子(monad),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7154518/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com