hdi*_*zle 3 haskell functional-programming
我写了这段代码:
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)]
Run Code Online (Sandbox Code Playgroud)
我希望仿函数应用于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]’
Run Code Online (Sandbox Code Playgroud)
我在这个问题上很丢失,有没有办法在整个列表中应用仿函数?或者我是否需要为单个Pixel类型设置仿函数,然后遍历列表?
根据我的理解,你会得到一个像素列表,你想要改变每个像素的第一个分量(即红色分量).因此,您需要以下功能:
changeAllPixels :: [Pixel Int] -> [Pixel Int]
Run Code Online (Sandbox Code Playgroud)
问:我们如何更改列表中的每个元素?答:我们使用map:
changeAllPixels = map changeOnePixel
changeOnePixel :: Pixel Int -> Pixel Int
Run Code Online (Sandbox Code Playgroud)
我们只想更改红色组件.因此,我们有:
changeOnePixel = changeRedComponent doSomething
changeRedComponent :: (a -> a) -> Pixel a -> Pixel a
changeRedComponent f (Pixel (r, g, b)) = Pixel (f r, g, b)
doSomething :: Int -> Int
Run Code Online (Sandbox Code Playgroud)
现在你只需要实现doSomething.例如,如果要反转红色组件,则可以doSomething按如下方式实现:
doSomething x = 255 - x
Run Code Online (Sandbox Code Playgroud)
请注意,我们没有制作Pixel实例Functor.这是因为我们只想更改红色组件并单独留下绿色和蓝色组件.然而map,我们使用的是fmap列表.
我认为你遇到的最大问题是你不能很好地理解仿函数.你可能应该花一些时间熟悉它们.