[英]Why does this function not fail immediately?
我有以下代碼。 main
獲取stdin
文本並通過g
對其進行排序,然后f
打印輸出,並返回一個適當的ExitCode
,該代碼使用exitWith
。
我的問題是,為什么該程序在使用示例輸入運行時沒有在輸入第一行( test
)后立即終止,而是在讀取第二行( test2
)后才失敗? 我想發生的事情是讓g
函數在parse1
返回Left "left: test"
之后parse1
返回,而不必等到輸入第二行。
碼:
import System.Exit
import Control.Monad
import Data.Either
type ErrType = String
parse1 :: String -> Either ErrType Int
parse1 "test" = Left "left: test"
parse1 _ = Left "left"
parse2 :: String -> Either ErrType Char
parse2 s = Right (head s)
g :: String -> Either String String
g str =
let l1:l2:ls = lines str
in either (Left . show) (Right . show) $ do
a <- parse1 l1
b <- parse2 l2
return "placeholder"
main = getContents >>= f.g >>= exitWith
where f (Right s) = putStrLn s >> return ExitSuccess
f (Left s) = putStrLn s >> return (ExitFailure 1)
標准輸入流:
test
test2
線
let l1:l2:ls = lines str
這意味着即使只評估l1
, 整個模式l1:l2:ls
需要匹配,這意味着需要檢查str
實際上至少包含兩行。 使用惰性輸入,將導致您看到的行為。
您可以使用顯式惰性模式來解決該問題,該模式可以延遲第二行的檢查:
let l1 : ~(l2:ls) = lines str
或者,由於let中的頂部模式隱式地是惰性的,您可以將其拆分為:
let l1:ls' = lines str
l2:ls = ls'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.