我已经写了这段代码:
newtype Pixel a = Pixel (a,a,a) deriving (Show)
instance Functor [Pixel Int] where
fmap f [] = []
fmap f [Pixel(a,b,c)] = [Pixel(f a, b, c)]
我希望仿函数应用于 Pixel
类型中的第一个元素,但我不断收到此错误:
New.hs:17:18: error:
• Expecting one fewer arguments to ‘[Pixel Int]’
Expected kind ‘* -> *’, but ‘[Pixel Int]’ has kind ‘*’
• In the first argument of ‘Functor’, namely ‘[Pixel Int]’
In the instance declaration for ‘Functor [Pixel Int]’
我在这个问题上很迷茫,有没有办法在整个列表上应用仿函数?还是我需要为单个 Pixel
类型设置一个仿函数,然后 然后 遍历一个列表?
最佳答案
据我了解,您得到了一个像素列表,并且您想要更改每个像素的第一个组件(即红色组件)。因此,您需要以下功能:
changeAllPixels :: [Pixel Int] -> [Pixel Int]
问:我们如何改变列表的每个元素? 答:我们使用map
:
changeAllPixels = map changeOnePixel
changeOnePixel :: Pixel Int -> Pixel Int
我们只想更改红色组件。因此,我们有:
changeOnePixel = changeRedComponent doSomething
changeRedComponent :: (a -> a) -> Pixel a -> Pixel a
changeRedComponent f (Pixel (r, g, b)) = Pixel (f r, g, b)
doSomething :: Int -> Int
现在你只需要实现doSomething
。例如,如果你想反转红色组件,那么你可以实现 doSomething
如下:
doSomething x = 255 - x
请注意,我们没有使 Pixel
成为 Functor
的实例。这是因为我们只想改变红色分量,而不管绿色和蓝色分量。然而,我们确实使用了 map
,它是列表的 fmap
。
我认为你最大的问题是你不太了解仿函数。您可能应该花一些时间来熟悉它们。
关于haskell - 为什么这个 Functor 实例不正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50322181/