2014-04-08 84 views
1

我想篩選我的項目列表中的屬性,我似乎無法讓它工作。基於記錄語法的項目篩選列表

我有被宣佈爲數據類型圖如下:

data Shape = Square {length:: Float, color:: Color} 
      | Rectangle {length:: Float, widht:: Float, color :: Color} 
      .... 

重複此一對夫婦的形狀 他們都共有的屬性爲顏色,這也是一種數據類型data Color = Yellow | Green | Blue

我試圖過濾顏色像這樣

getByColor :: Color -> [Shape] -> [Shape] 
getByColor _ [] = [] 
getByColor x [email protected]{color=c}:xs 
          | c == x = item:getByColor x xs 
          | otherwise = getByColor x items 

這給了我一個語法錯誤「{」,當我嘗試運行它。

有人可以指出我在正確的方向?

回答

3

我一直在想我的問題。 一個匿名函數完成了這項工作。

記錄語法讓你自動訪問功能,所以我能做到以下幾點

getByColor :: Color -> [Shape] -> [Shape] 
getByColor colorParam shapes = filter (\shape -> color shape == colorParam) shapes 
+0

你可以寫'(\形狀 - >顏色形狀== colorParam)''爲((== colorParam)顏色)' – Simon

+0

@Simon:或者,用'Control.Arrow',爲'色>>>(== colorParam)'! – Xeo

0

這是不是直接回答你的問題,但一些建議。通常不鼓勵使用求和類型和記錄語法,因爲記錄字段的非全部使用可以隱藏編譯器的錯誤,並延遲到運行時。例如,如果在Shape上調用width,代碼將編譯,但在形狀爲Square的情況下,將在運行時引發異常。

將特定於形狀的行爲放到它們自己的類型中並通過新的類型參數化Shape中的構造函數通常是有意義的 - 只有使用記錄字段(如果它是全部的話)纔會爲所有構造函數定義。

儘管在這種情況下,我建議不要使用記錄語法,因爲您可以簡單地在常規產品中定義所有您希望作爲獨立函數的字段 - 並且不要從模塊中暴露Shape構造函數 - 功能來創建它們。

module Shape (Shape, square, rectangle, length, color, width) where 

import Prelude hiding (length) 

data Shape = Square Float Color 
      | Rectangle Float Float Color 
      deriving (Eq, Show) 

square = Square 
rectangle = Rectangle 

length (Square l _) = l 
length (Rectangle l _ _) = l 

color (Square _ c) = c 
color (Rectangle _ _ c) = c 

width (Rectangle _ w _) = Just w 
width _ = Nothing