【问题标题】:Idris - lazy evaluation issueIdris - 懒惰的评估问题
【发布时间】:2018-03-31 04:53:30
【问题描述】:

考虑这个程序:

module test

import Effects
import Effect.StdIO

(>>==) : Maybe a -> Lazy (a -> Maybe b) -> Maybe b
(>>==) Nothing (Delay map) = Nothing
(>>==) (Just x) (Delay map) = map x

nothing : String -> Eff (Maybe String) [STDIO]
nothing s = do
    putStrLn s
    pure Nothing

func : Maybe String -> String -> Maybe String
func Nothing _ = Nothing
func (Just s) t = Just (s ++ t)

test : Eff () [STDIO]
test = do
    let m = !(nothing "a") >>== (func !(nothing "b"))
    putStrLn "end"

main : IO ()
main = run test

由于>>== 的右侧被声明为惰性并且!(nothing "a") 返回Nothing,我希望>>== 的右侧不会被评估。

但实际上它确实得到了评​​估,我不明白为什么......

更广泛地说,我正在尝试连接可能返回的 Eff 计算,并在我得到第一个 Nothing 时停止执行

【问题讨论】:

    标签: monads lazy-evaluation idris


    【解决方案1】:

    脱糖!符号。

    test = do
        x <- nothing "a"
        y <- nothing "b"
        let m = x >>== (func y)
        putStrLn "end"
    

    显然“a”、“b”和“end”都会被打印出来,但func可能不会被评估。

    我认为您需要定义 &gt;&gt;== 才能作用于(某些)Eff 值,而不是直接作用于 Maybes。

    HTH

    【讨论】:

    • 我真正想要的是在nothing "a" 之后停止计算,因此永远不会打印"b"。我猜这不会发生,因为do 符号在错误的上下文中工作,即Eff 而不是Maybe。在 Haskell 中,我会使用 MaybeT monad 转换器来解决这个问题,在 Idris 中是否有类似的东西?依赖类型是否允许我做一些更清洁的事情?
    • 添加EXCEPTION () 效果。让nothing 调用raise (),已经有一个基于 Maybe 定义的处理程序,无论你提出什么问题都可以工作。
    猜你喜欢
    • 2019-01-07
    • 2010-11-17
    • 1970-01-01
    • 2015-09-06
    • 2016-12-14
    • 2021-12-25
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多