我有这些数据类型
data RGB = RGB Int Int Int
data Grid a = G [[a]]
和一个功能
returnFirstRed :: Grid RGB -> Int
基本上,该函数返回RGB值的双数组中的第一个颜色值。
网格RGB看起来像
G[[RGB 50, 50, 50, RGB 100,200, 200],
[RGB, 75,75,75, RGB 80,80,80]]
所以对于这个网格,我想要返回50.
我的问题是模式匹配并从网格中提取RGB值。
做
returnFirstRed (G xs) = (head xs) !! 0
产生RGB值而不是int
我已经尝试了很多不同的方法来获得r值,但我无法让它工作,我无法在任何地方找到类似的例子。我正在努力学习Haskell并且很遗憾在这里做什么..
答案 0 :(得分:7)
您可以在不使用head
或!! 0
(其中head
被视为更好的顺便说一句)的情况下完全匹配模式。 [1,2,3]
是1:2:3:[]
的语法糖(在ghci
中尝试),因此您可以将列表的头部与x:rest
匹配,如果您不需要其余部分,只是x:_
。
但是你为returnFirstRed (G [[]])
返回什么,即输入列表是否为空?我建议改为返回Maybe
,这样您就可以返回Nothing
输入空列表。
returnFirstRed :: Grid RGB -> Maybe Int
returnFirstRed (G (((RGB r _ _):_):_)) = Just r
returnFirstRed _ = Nothing
答案 1 :(得分:2)
你想要的是
returnFirstRed (G ((RGB x _ _):_):_)) = x
请注意,x是RGB中的第一个元素,它是列表的头部,它是另一个列表的头部,这是G中唯一的元素。
当然,你可以根本不使用模式匹配,或者使用一些模式匹配,或者它们之间的任何中间。实践中的一个例子是:
returnFirstRed (G x) = extractFromRGB $ head $ head x
where extractFromRGB (RGB y _ _) = y
答案 2 :(得分:2)
使代码工作的最小变化是对提取的RGB
值进行模式匹配。
returnFirstRed (G xs) = let RGB x _ _ = (head xs) !! 0 in x
请注意head xs
与xs !! 0
相同,如果您想更均匀地编写:{/ p>
returnFirstRed (G xs) = let RGB x _ _ = xs !! 0 !! 0 in x
答案 3 :(得分:1)
定义您的访问者方法
red,green,blue :: RGB -> Int
red (RGB r _ _) = r
green (RGB _ g _) = g
blue (RGB _ _ b) = b
first :: Grid a -> [a]
first (G as) = head as
现在你可以写
了> grid = G [[RGB 50 50 50, RGB 100 200 200], [RGB 75 75 75, RGB 80 80 80]]
> red $ head $ first grid
50