`bind`/`flatMap`/`>>=` over Optional in Dhall

`bind`/`flatMap`/`>>=` over Optional in Dhall

我需要 bind/flatMap/>>= 在 Dhall 的 Optional

我找不到它的实现,于是想出了我自己的实现。

let bindOptional
    : ∀(a : Type) → ∀(b : Type) → (a → Optional b) → Optional a → Optional b
    = λ(a : Type) →
      λ(b : Type) →
      λ(f : a → Optional b) →
      λ(o : Optional a) →
        Prelude.Optional.fold a o (Optional b) f (None b)

然后我按如下方式使用

bindOptional Outer Inner (λ(x : Outer) → x.inner) outer

Prelude中真的没有定义这个函数吗?我想我可能错过了。

此外:

  1. 是否有更惯用的定义方式?

  2. 是否有可能利用类型推断来缩短调用时间?像

    bindOptional _.inner outer -- the compiler infers `Outer` from `outer` and `Inner` from `_.inner`  
    

我试图不给出类型参数,但似乎不可能(由于我对语言的了解有限)。

在撰写本文时,Prelude 中还没有针对 Optional 的此类操作,尽管没有特别说明为什么它不存在,因此您可以打开一个拉取请求来添加它。

最接近语言支持的机制是使用 merge 关键字作用于 Optional 值这一事实,所以这会起作用:

merge { Some = λ(_ : Inner) → _.inner, None = None SomeType } outer

…尽管这仍然需要指定 InnerSomeType 类型,因此它不利用类型推断。