我有一个数据类型,可以跟踪数字的"块"(有点像矩阵).
newtype Block a = Block [[a]]
Run Code Online (Sandbox Code Playgroud)
我想把它作为一个实例Functor.但是,我试图以fmap可以应用于整个列表块的方式来执行此操作,以便fmap具有类型fmap :: [[a]] -> [[b]]而不是类型fmap :: a -> b.
原因是因为我想映射到我的Block仿函数函数transpose,这些函数适用于列表块[[a]]而不是每个元素a.也就是说,我希望能够定义像这样的函数
transposeBlock :: Block a -> Block a
transposeBlock = (transpose <$>)
Run Code Online (Sandbox Code Playgroud)
我试图将我的仿函数实例声明如下.
instance Functor (Block [[a]]) where
fmap f (Block x) = Block (f x)
Run Code Online (Sandbox Code Playgroud)
但是我遇到了尝试编译它时出现的类型错误.
error:
• Expecting one fewer argument to ‘Block [[a]]’
Expected kind ‘* -> *’, but ‘Block [[a]]’ has kind ‘*’
• In the first argument of ‘Functor’, namely ‘Block [[a]]’
In the instance declaration for ‘Functor (Block [[a]])’
Run Code Online (Sandbox Code Playgroud)
有什么方法可以将函数映射到[[a]]我的Block类型的列表块中?
对不起,您无法调用该功能fmap.但那没关系,那里有很多其他好名字.
onBlock :: ([[a]] -> [[b]]) -> Block a -> Block b
onBlock f (Block v) = Block (f v)
Run Code Online (Sandbox Code Playgroud)
如果你愿意的话,你甚至可以给它一个充满了不明显的标点符号的名字.
(<#>) :: ([[a]] -> [[b]]) -> Block a -> Block b
f <#> Block v = Block (f v)
Run Code Online (Sandbox Code Playgroud)