Haskell双数组模式匹配

时间:2016-04-12 21:05:22

标签: haskell

我有这些数据类型

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并且很遗憾在这里做什么..

4 个答案:

答案 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 xsxs !! 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