我有以下数据类型:
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部分。
答案 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
但是上面的紧凑语法较短,因此在这种情况下效果更好。
True
形式时返回Front _
-然后作为参数传递给filter
。