Haskell: 使用泛型时尝试输入错误
Haskell: Type Error Trying when using generics
我是一个Haskell初学者,当我编译Haskell源代码的时候,试图让一个函数实现一个lazy至少只要
module Main where
import Data.Maybe
main = undefined
foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
foldWhilel f acc xs = go acc xs
where
go :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
go acc [] = Just acc
go acc (x:xs) = if isNothing new_acc then Just acc else go (fromJust new_acc) xs
where
new_acc :: Maybe b
new_acc = f x acc
考虑到(至少就我所知)这应该可以完美运行,但出现了这个令人讨厌的愚蠢的废话错误。因为函数go和函数参数在类型注解中设计的很好
dist-newstyle/gh.hs:15:19: error:
• Couldn't match type ‘b2’ with ‘b’
‘b2’ is a rigid type variable bound by
the type signature for:
new_acc :: forall b2. Maybe b2
at dist-newstyle/gh.hs:14:9-26
‘b’ is a rigid type variable bound by
the type signature for:
foldWhilel :: forall a b.
(a -> b -> Maybe b) -> b -> [a] -> Maybe b
at dist-newstyle/gh.hs:7:1-56
Expected type: Maybe b2
Actual type: Maybe b
• In the expression: f x acc
In an equation for ‘new_acc’: new_acc = f x acc
In an equation for ‘go’:
go acc (x : xs)
= if isNothing new_acc then Just acc else go (fromJust new_acc) xs
where
new_acc :: Maybe b
new_acc = f x acc
• Relevant bindings include
new_acc :: Maybe b2 (bound at dist-newstyle/gh.hs:15:9)
f :: a -> b -> Maybe b (bound at dist-newstyle/gh.hs:8:12)
foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
(bound at dist-newstyle/gh.hs:8:1)
|
15 | new_acc = f x acc
| ^^^^^^^
dist-newstyle/gh.hs:15:21: error:
• Couldn't match expected type ‘a’ with actual type ‘a1’
‘a1’ is a rigid type variable bound by
the type signature for:
go :: forall b1 a1. b1 -> [a1] -> Maybe b1
at dist-newstyle/gh.hs:10:5-29
‘a’ is a rigid type variable bound by
the type signature for:
foldWhilel :: forall a b.
(a -> b -> Maybe b) -> b -> [a] -> Maybe b
at dist-newstyle/gh.hs:7:1-56
• In the first argument of ‘f’, namely ‘x’
In the expression: f x acc
In an equation for ‘new_acc’: new_acc = f x acc
• Relevant bindings include
xs :: [a1] (bound at dist-newstyle/gh.hs:12:15)
x :: a1 (bound at dist-newstyle/gh.hs:12:13)
go :: b1 -> [a1] -> Maybe b1 (bound at dist-newstyle/gh.hs:11:5)
f :: a -> b -> Maybe b (bound at dist-newstyle/gh.hs:8:12)
foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
(bound at dist-newstyle/gh.hs:8:1)
|
15 | new_acc = f x acc
| ^
dist-newstyle/gh.hs:15:23: error:
• Couldn't match expected type ‘b’ with actual type ‘b1’
‘b1’ is a rigid type variable bound by
the type signature for:
go :: forall b1 a1. b1 -> [a1] -> Maybe b1
at dist-newstyle/gh.hs:10:5-29
‘b’ is a rigid type variable bound by
the type signature for:
foldWhilel :: forall a b.
(a -> b -> Maybe b) -> b -> [a] -> Maybe b
at dist-newstyle/gh.hs:7:1-56
• In the second argument of ‘f’, namely ‘acc’
In the expression: f x acc
In an equation for ‘new_acc’: new_acc = f x acc
• Relevant bindings include
acc :: b1 (bound at dist-newstyle/gh.hs:12:8)
go :: b1 -> [a1] -> Maybe b1 (bound at dist-newstyle/gh.hs:11:5)
f :: a -> b -> Maybe b (bound at dist-newstyle/gh.hs:8:12)
foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
(bound at dist-newstyle/gh.hs:8:1)
|
15 | new_acc = f x acc
|
修复错误的最简单方法是删除 go
和 new_acc
.
的类型签名
你不能这样使用类型签名,因为说 foldWhilel
的签名中使用的 b
和 new_acc
的签名中使用的 b
是两个完全不同的变量恰好有相似的名字。最重要的是,go
中的 (a -> b -> Maybe b)
签名无论如何都是错误的(go
没有这样的参数,正在从外部范围使用 f
)。
如果你想在整个功能中使用b
具有相同的含义,你需要启用并应用Scoped type variables:
{-# Language ScopedTypeVariables #-}
import Data.Maybe
foldWhilel :: forall a b. (a -> b -> Maybe b) -> b -> [a] -> Maybe b
foldWhilel f acc xs = go acc xs
where
go :: b -> [a] -> Maybe b
go acc [] = Just acc
go acc (x:xs) = if isNothing new_acc then Just acc else go (fromJust new_acc) xs
where
new_acc :: Maybe b
new_acc = f x acc
我是一个Haskell初学者,当我编译Haskell源代码的时候,试图让一个函数实现一个lazy至少只要
module Main where
import Data.Maybe
main = undefined
foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
foldWhilel f acc xs = go acc xs
where
go :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
go acc [] = Just acc
go acc (x:xs) = if isNothing new_acc then Just acc else go (fromJust new_acc) xs
where
new_acc :: Maybe b
new_acc = f x acc
考虑到(至少就我所知)这应该可以完美运行,但出现了这个令人讨厌的愚蠢的废话错误。因为函数go和函数参数在类型注解中设计的很好
dist-newstyle/gh.hs:15:19: error:
• Couldn't match type ‘b2’ with ‘b’
‘b2’ is a rigid type variable bound by
the type signature for:
new_acc :: forall b2. Maybe b2
at dist-newstyle/gh.hs:14:9-26
‘b’ is a rigid type variable bound by
the type signature for:
foldWhilel :: forall a b.
(a -> b -> Maybe b) -> b -> [a] -> Maybe b
at dist-newstyle/gh.hs:7:1-56
Expected type: Maybe b2
Actual type: Maybe b
• In the expression: f x acc
In an equation for ‘new_acc’: new_acc = f x acc
In an equation for ‘go’:
go acc (x : xs)
= if isNothing new_acc then Just acc else go (fromJust new_acc) xs
where
new_acc :: Maybe b
new_acc = f x acc
• Relevant bindings include
new_acc :: Maybe b2 (bound at dist-newstyle/gh.hs:15:9)
f :: a -> b -> Maybe b (bound at dist-newstyle/gh.hs:8:12)
foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
(bound at dist-newstyle/gh.hs:8:1)
|
15 | new_acc = f x acc
| ^^^^^^^
dist-newstyle/gh.hs:15:21: error:
• Couldn't match expected type ‘a’ with actual type ‘a1’
‘a1’ is a rigid type variable bound by
the type signature for:
go :: forall b1 a1. b1 -> [a1] -> Maybe b1
at dist-newstyle/gh.hs:10:5-29
‘a’ is a rigid type variable bound by
the type signature for:
foldWhilel :: forall a b.
(a -> b -> Maybe b) -> b -> [a] -> Maybe b
at dist-newstyle/gh.hs:7:1-56
• In the first argument of ‘f’, namely ‘x’
In the expression: f x acc
In an equation for ‘new_acc’: new_acc = f x acc
• Relevant bindings include
xs :: [a1] (bound at dist-newstyle/gh.hs:12:15)
x :: a1 (bound at dist-newstyle/gh.hs:12:13)
go :: b1 -> [a1] -> Maybe b1 (bound at dist-newstyle/gh.hs:11:5)
f :: a -> b -> Maybe b (bound at dist-newstyle/gh.hs:8:12)
foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
(bound at dist-newstyle/gh.hs:8:1)
|
15 | new_acc = f x acc
| ^
dist-newstyle/gh.hs:15:23: error:
• Couldn't match expected type ‘b’ with actual type ‘b1’
‘b1’ is a rigid type variable bound by
the type signature for:
go :: forall b1 a1. b1 -> [a1] -> Maybe b1
at dist-newstyle/gh.hs:10:5-29
‘b’ is a rigid type variable bound by
the type signature for:
foldWhilel :: forall a b.
(a -> b -> Maybe b) -> b -> [a] -> Maybe b
at dist-newstyle/gh.hs:7:1-56
• In the second argument of ‘f’, namely ‘acc’
In the expression: f x acc
In an equation for ‘new_acc’: new_acc = f x acc
• Relevant bindings include
acc :: b1 (bound at dist-newstyle/gh.hs:12:8)
go :: b1 -> [a1] -> Maybe b1 (bound at dist-newstyle/gh.hs:11:5)
f :: a -> b -> Maybe b (bound at dist-newstyle/gh.hs:8:12)
foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
(bound at dist-newstyle/gh.hs:8:1)
|
15 | new_acc = f x acc
|
修复错误的最简单方法是删除 go
和 new_acc
.
你不能这样使用类型签名,因为说 foldWhilel
的签名中使用的 b
和 new_acc
的签名中使用的 b
是两个完全不同的变量恰好有相似的名字。最重要的是,go
中的 (a -> b -> Maybe b)
签名无论如何都是错误的(go
没有这样的参数,正在从外部范围使用 f
)。
如果你想在整个功能中使用b
具有相同的含义,你需要启用并应用Scoped type variables:
{-# Language ScopedTypeVariables #-}
import Data.Maybe
foldWhilel :: forall a b. (a -> b -> Maybe b) -> b -> [a] -> Maybe b
foldWhilel f acc xs = go acc xs
where
go :: b -> [a] -> Maybe b
go acc [] = Just acc
go acc (x:xs) = if isNothing new_acc then Just acc else go (fromJust new_acc) xs
where
new_acc :: Maybe b
new_acc = f x acc