使用递归确定子集

时间:2019-02-02 20:16:19

标签: haskell recursion set subset infinite-loop

我正在尝试编写一个函数deletepost(e) { let a = e.target.id; console.log(a); } render() { return ( <div> { this.props.posts.map((post, i) => <div id="a" key="1"> <span> <h3>{post.title}</h3><p>{post.post}</p></span> <input type="button" value="Delete" id="1" onClick={this.deletepost}/> </div> ) } </div> ) } } ,该函数具有两个列表并确定第一个元素是否出现在第二个列表中。

当输入如下所示的函数时,代码将编译为GHCi,但不会运行(即卡住):

subset

这是我的代码:

subset [1,2] [1,2]

谢谢!

3 个答案:

答案 0 :(得分:4)

subset (x:xs) ys
 | elem x ys = subset (x:xs) ys
                   -- ^^^^^^ --

请注意,上面的递归调用不会更改参数!这将导致无限递归。您要在进行递归调用之前删除x

答案 1 :(得分:4)

让我们仔细看一下代码片段:

subset (x:xs) ys
 | elem x ys = subset (x:xs) ys

elem x ys成立的情况下(完全合理),您拥有

subset (x:xs) ys = subset (x:xs) ys

,其执行在其任何参数没有减少,只是重复相同呼叫重新

因此,无限循环。

使用布尔值时,习惯上使用逻辑连接词,这通常会导致更简洁明了的定义:

subset (x:xs) ys = elem x ys && subset ..... .....

是您所需要的,因为(&&)的真值表是

    True  && x  =  x
    False && _  =  False

即当第一个参数为false时,甚至不检查第二个参数的值。

答案 2 :(得分:4)

不需要显式递归;您可以使用all来验证(`elem` ys)中每个值的正确性xs

subset xs ys = all (`elem` ys) xs