对自定义数据类型使用过滤器

时间:2019-06-23 13:01:45

标签: haskell filter

我有以下数据类型:

data Command = Back Int | Front Val deriving (Show,Eq)
data Val = Val {first::Int, second::Int, third::Int} deriving (Show, Eq)
type Program = [Command]

我有这个功能:

foo :: Program -> Int
foo list = length (filter (==Front Val {first, second, third}) list)

目的是仅使用FILTER来查找Front发生的次数,而foo给出编译错误。我不确定如何表示Front的整数/ val部分。

2 个答案:

答案 0 :(得分:5)

如果变量wynik = et.getText().toString();(==) :: Eq a => a -> a -> Bool没有值,则不能对它们进行相等检查first。这里您需要的是模式匹配

例如,我们可以使用列表理解:

second

因为foo :: Program -> Int foo list = length [ v | v@(Front _) <- list ]类型的唯一数据构造函数是Val {},所以不需要将参数与Val _ _ _Val等匹配。

如果您认为以后会添加更多的数据构造函数,则可以添加额外的子模式:

Val

或者我们可以在函数中进行模式匹配,并使用foo :: Program -> Int foo list = length [ v | v@(Front (Val {})) <- list ],例如:

filter :: (a -> Bool) -> [a] -> [a]

或者如果我们包含foo :: Program -> Int foo = length . filter f where f (Front _) = True f _ = False数据构造函数检查:

Val

答案 1 :(得分:5)

正如@WillemVanOnsem在他的回答中所说,您使用的方法不起作用。尝试使用filter (\x -> case x of { Front _ -> True; Back _ -> False }) list。您也许可以单独解决它的工作原理,但是如果您需要更多详细信息:

  • \x -> case x of { Front _ -> True; Back _ -> False } lambda表达式。它定义了一个未命名(或 anonymous )函数,该函数采用一个名为x的参数,并返回case x of { Front _ -> True; Back _ -> False }给定的值。
  • case x of { Front _ -> True; Back _ -> False }x进行模式匹配。如果x的格式为Front _,其中_可以是任何值,则它返回True;否则返回False。通常,此语句的格式如下:
case x of
    Front _ -> True
    Back _ -> False

但是上面的紧凑语法较短,因此在这种情况下效果更好。

  • 上面的lambda表达式-如前所述,当其参数为True形式时返回Front _-然后作为参数传递给filter