我正在尝试重构以下(工作)代码(优秀NICTA Haskell course的一部分):
instance Extend ListZipper where
f <<= z =
ListZipper (unfoldr ((<$>) (\z' -> (f z', z')) . toOptional . moveLeft) z)
(f z)
(unfoldr ((<$>) (\z' -> (f z', z')) . toOptional . moveRight) z)
以下内容:
instance Extend ListZipper where
f <<= z = ListZipper (go moveLeft) (f z) (go moveRight)
where go f = unfoldr ((<$>) (\z' -> (f z', z')) . toOptional . f) z
但不幸的是我得到以下编译错误:
src/Course/ListZipper.hs:669:25:
Couldn't match type `b' with `MaybeListZipper a'
`b' is a rigid type variable bound by
the type signature for
<<= :: (ListZipper a -> b) -> ListZipper a -> ListZipper b
at src/Course/ListZipper.hs:669:3
Expected type: List b
Actual type: List (MaybeListZipper a)
In the return type of a call of `go'
In the first argument of `ListZipper', namely `(go moveLeft)'
In the expression: ListZipper (go moveLeft) (f z) (go moveRight)
我是否错过了一些小事或者更基本的事情?
在惯用的Haskell中,这样的重构是否可能(甚至是可取的)?
答案 0 :(得分:4)
您正在使用新f
为原始f
投影。尝试重命名第二个f
,如
instance Extend ListZipper where
f <<= z = ListZipper (go moveLeft) (f z) (go moveRight)
where go g = unfoldr ((<$>) (\z' -> (f z', z')) . toOptional . g) z
答案 1 :(得分:3)
您在这里使用f
,它引用了<<=
的第一个操作数。
(unfoldr ((<$>) (\z' -> (f z', z')) . toOptional . moveLeft) z)
在此处使用时,它指的是传递给go
的函数。
where go f = unfoldr ((<$>) (\z' -> (f z', z')) . toOptional . f) z
选择一个不同的名字!