我试图在Haskell中定义一个函数来检查列表A中的元素是否都在列表B中并返回一个布尔值。
所以给出以下内容:
listb = [a,b,c,d]
function :: [char]->Bool
该函数应检查输入列表是否只包含listb的元素 输入列表也不能超过n 的长度。
这些是我尝试过的一些方法,但它们似乎都不起作用:
function :: [char] -> Bool
function xs = length xs == n && isElem xs
isElem :: [char] -> Bool
isElem (x:xs) = x `elem` listb && isElem xs
有效输入失败。
我也尝试过:
function :: [char] -> Bool
function xs = length xs == n && whileValid xs
whileValid :: [char] -> Bool
whileValid (x:xs)
|x `elem` listb = True && whileValid xs
|otherwise = False
出于同样的原因失败了。
这些方法有什么问题,如何定义此功能才能使用?
答案 0 :(得分:3)
听起来你正试图检查两个不相关的东西:
列表xs
的元素是否是另一个列表{@ 1}}的元素的子集?
ys
的长度最多是xs
吗?
最简单的方法是分别检查这些。
n
您可以通过将这些操作组合在一起来节省更多时间,但我的手机电池电量不足,所以我会留待以后使用。
答案 1 :(得分:3)
将概念概括为任何类型Eq
类的实例,您可以按如下方式进行操作;
import Control.Applicative
exists :: Eq a => [a] -> [a] -> Bool
exists x y = any id $ (==) <$> x <*> y
*Main> exists [1,2,3] [3,4,5]
True
*Main> exists [1,2,3] [7,4,5]
False
答案 2 :(得分:2)
您的代码存在一些问题:
类型以大写字母开头,其中类型变量以小写字母开头,因此
function :: [char] -> Bool
不是你想要的,而是function :: [Char] -> Bool
,我会写isSubSet :: String -> Bool
或更一般的isSubSet :: Eq a => [a] -> Bool
。
通常在haskell中,您不使用像
这样的全局常量listB :: [Char]
listB = ['a'..'d']
而是参数化函数 - 所以
isSubSetOf :: String -> String -> Bool
isSubSetOf [] _ = True
isSubSetOf small@(x:xs) big = (length small <= length big)
&& (x `elem` big && isSubsetOf xs big)
isSubSet x = isSubSetOf x listB
将是类型签名的正确实现,它是一个完整的函数,这是一种奇特的说法 - 处理所有输入类型的情况,你错过了列表的基本情况,即处理空列表。
但它有一些(逻辑)错误需要解决:
length
都没有必要,实际上根本没有必要 - 这会减慢你的算法速度!isSubSetOf "aab" "abbb"
。