【问题标题】:Why does this function not fail immediately?为什么此功能不会立即失败?
【发布时间】:2015-03-10 02:24:02
【问题描述】:

我有以下代码。 main 获取stdin 文本并通过g 对其进行排序,然后f 打印它的输出并返回一个适当的ExitCode,该ExitCode 是使用exitWith 提交的。

我的问题是为什么这个程序在使用示例输入运行时,在输入第一行 (test) 后没有立即终止,而是在读取第二行 (test2) 后才失败?我想要发生的是g 函数在parse1 返回Left "left: test" 之后立即返回,而不是等到输入第二行。

代码:

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

【问题讨论】:

    标签: haskell monads


    【解决方案1】:

    线

    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'
    

    【讨论】:

    • 谢谢!我不熟悉 ~ 语法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 2020-12-04
    相关资源
    最近更新 更多