haskell - 使用 fclabel 中的 'left' 镜头时出现类型错误

标签 haskell lenses

我制作了一个用于测试 fclabel 的最小示例。使用镜头从 Either 值中检索“正确”值。为什么会失败?我错过了什么吗?

module Label where
import Data.Label
import Data.Label.Base

test = get right (Right "test")

{- Will fail with this message:
Label.hs:5:12:
    No instance for (Control.Arrow.ArrowZero Data.Label.Point.Total)
      arising from a use of `right'
    Possible fix:
      add an instance declaration for
      (Control.Arrow.ArrowZero Data.Label.Point.Total)
    In the first argument of `get', namely `right'
    In the expression: get right (Right "test")
    In an equation for `test': test = get right (Right "test")
Failed, modules loaded: none.

-- Tested with fclabels-2.0.2
-}

最佳答案

这个错误相当晦涩,但是当我们查看 get 的类型和文档时,它会变得更加清晰。和 right :

get :: (f :-> a) -> f -> a
type :-> f o = Lens Total f o

right :: (ArrowZero arr, ArrowApply arr, ArrowChoice arr)
      => Lens arr (Either a b -> Either a o) (b -> o)

-- Lens pointing to the right value in an Either. (Partial and polymorphic)

本质上,您使用的get仅适用于镜头,但right不是总镜头,因为它不会如果值为 Left,则有效。该错误表示部分镜头要求载体类型为 ArrowZero,但总镜头无法做到这一点。

如果您在 ghci 中进行实验,只需调用 get right(不带任何参数)就会出现此错误。

如果将 Data.Label 的导入更改为 Data.Label.Partial ,那么你的代码就可以工作了。 test 最终得到类型 Maybe String

关于haskell - 使用 fclabel 中的 'left' 镜头时出现类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26370141/

相关文章:

Haskell - 在 newtype 上的 iso

scala - 具有错误处理功能的镜头/棱镜

haskell - 如何将 Control.Monad.State 与 Parsec 结合使用?

haskell - 使用 ekmett 的 Lens 更新一个字段的多个子字段

list - Haskell 持久列表

haskell - 在 O(depth) 中填充树的函数

scala - 使用 Argonaut Lenses 从 JSON 对象的 JSON 数组中提取值

haskell - 镜头中的观看和使用有什么区别?

haskell - 在什么情况下通用子表达式消除会影响 Haskell 程序的惰性?

haskell - Haskell 库类型类的最低规范?