弄乱镜头时输入错误
Type error when messing up with lenses
我在尝试编译一些镜头代码时遇到类型错误。
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens.Setter (over)
import Control.Lens.Getter (view)
import Control.Lens.TH
data IL = IL {
_ilL :: [Int]
}
deriving (Show)
makeLenses ''IL
val = IL [1, 2, 3]
(val1, val2) = let l = ilL
in (over l tail val, view l val)
错误是:
Test.hs:17:35:
Couldn't match expected type `Control.Lens.Internal.Getter.Accessor [Int] [Int]'
with actual type `Control.Lens.Internal.Setter.Mutator [Int]'
Expected type: Control.Lens.Getter.Getting [Int] s0 [Int]
Actual type: ([Int]
-> Control.Lens.Internal.Setter.Mutator [Int])
-> IL -> Control.Lens.Internal.Setter.Mutator IL
In the first argument of `view', namely `l'
In the expression: view l val
如果我直接使用 ilL,这个错误就会消失。但是,我真的需要使用 let 来定义镜头。我该如何解决?
又一个可怕的单态限制的例子。在文件顶部添加 {-# LANGUAGE NoMonormorphismRestriction #-}
,它会编译得很好。
原因是因为当你在没有显式类型签名(或 MR 禁用)的情况下执行 let l = ilL in ...
时,GHC 希望尽可能地专门化 l
的类型。它首先在 over l tail val
中遇到它的使用,并特化到那里需要的类型,但这与 view l val
中的特化推断类型冲突。解决方案是禁用 MR 或添加显式类型签名,如
(val1, val2) =
let l :: Lens' IL [Int]
l = ilL
in (over l tail val, view l val)
这与更简单的情况非常相似,例如
x = let y = 1
z = 2 :: Int
w = 3 :: Double
in (z + y, w + y)
y
的类型应该是什么?对于 MR,编译器希望将 y
的类型限制为单一类型,但我们真的希望它具有 Num a => a
类型,因为这可以与 Int
s 或 Double
s。在 MR 关闭的情况下,编译器不会专门化 y
的类型,并且一切都按预期工作。另一种方法是给 y
一个明确的类型签名,但是当我们可以让编译器为我们做这些时,为什么还要这样做呢?
我在尝试编译一些镜头代码时遇到类型错误。
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens.Setter (over)
import Control.Lens.Getter (view)
import Control.Lens.TH
data IL = IL {
_ilL :: [Int]
}
deriving (Show)
makeLenses ''IL
val = IL [1, 2, 3]
(val1, val2) = let l = ilL
in (over l tail val, view l val)
错误是:
Test.hs:17:35:
Couldn't match expected type `Control.Lens.Internal.Getter.Accessor [Int] [Int]'
with actual type `Control.Lens.Internal.Setter.Mutator [Int]'
Expected type: Control.Lens.Getter.Getting [Int] s0 [Int]
Actual type: ([Int]
-> Control.Lens.Internal.Setter.Mutator [Int])
-> IL -> Control.Lens.Internal.Setter.Mutator IL
In the first argument of `view', namely `l'
In the expression: view l val
如果我直接使用 ilL,这个错误就会消失。但是,我真的需要使用 let 来定义镜头。我该如何解决?
又一个可怕的单态限制的例子。在文件顶部添加 {-# LANGUAGE NoMonormorphismRestriction #-}
,它会编译得很好。
原因是因为当你在没有显式类型签名(或 MR 禁用)的情况下执行 let l = ilL in ...
时,GHC 希望尽可能地专门化 l
的类型。它首先在 over l tail val
中遇到它的使用,并特化到那里需要的类型,但这与 view l val
中的特化推断类型冲突。解决方案是禁用 MR 或添加显式类型签名,如
(val1, val2) =
let l :: Lens' IL [Int]
l = ilL
in (over l tail val, view l val)
这与更简单的情况非常相似,例如
x = let y = 1
z = 2 :: Int
w = 3 :: Double
in (z + y, w + y)
y
的类型应该是什么?对于 MR,编译器希望将 y
的类型限制为单一类型,但我们真的希望它具有 Num a => a
类型,因为这可以与 Int
s 或 Double
s。在 MR 关闭的情况下,编译器不会专门化 y
的类型,并且一切都按预期工作。另一种方法是给 y
一个明确的类型签名,但是当我们可以让编译器为我们做这些时,为什么还要这样做呢?