簡體   English   中英

為什么此功能不會立即失敗?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM