2016-02-25 114 views
0

我似乎无法包装我的头如何通过Haskell列表列表进行递归。这是我的问题:Haskell - 通过列表列表递归?

type Symbol = String 
type Sentence = [[Symbol]] 

getSymbols :: [Sentence] -> [Symbol] 
getSymbols [[]] = [] 
getSymbols ((sym:stmt):(stmts)) 
    | stmt == [] = getSymbols stmts 
    | sym `elem` stmt = getSymbols ((stmt):(stmts)) 
    | otherwise = sym : getSymbols ((stmt):(stmts)) 

我想要返回给定句子中找到的所有符号列表中没有重复出现,例如,

getSymbols [["A","B","C"],["D","A"],["E","B","C"]] 

将返回:

["A","B","C","D","E"] --order does not matter-- 

我一直在尝试一些不同的方法,但似乎仍不能得到 - 我现在仍然在哈斯克尔相当原始,所以也许有一些明显的我我错过了。帮助将不胜感激,谢谢。

+0

你可能会尝试将问题分解为更容易的子问题?例如。首先创建一个包含所有内容的大列表,然后删除重复项。那么你的问题的答案就是编写这些简单的函数。 – gallais

+0

@gallais是否需要我编写更多的函数,还是可以在单个函数中完成?因为我只想用一个函数来解决问题 – willrobertshaw

+2

@willrobertshaw我不认为这是个好主意。函数式编程的核心是组成函数。您越早习惯编写小型可组合函数越好。想想什么是更通用的小型乐高积木或玩具车? – epsilonhalbe

回答

1

试试这个:

import Data.List 
nub . concat $ [["A","B","C"],["D","A"],["E","B","C"]] 
+3

你会添加一些解释,显然OP是不感兴趣的结果,但如何以及为什么 – epsilonhalbe

1

试试这个:

getSymbols   [] = [] 
getSymbols ( [] :xss) = getSymbols xss 
getSymbols ((x:xs):xss) 
    | x `elem` (getSymbols (xs:xss)) =  getSymbols (xs:xss) 
    | otherwise      = x : (getSymbols (xs:xss)) 
+0

嗨 - 我试过这个,但我在最后一行发生类型错误“无法匹配类型'[Char]'与'字符' 预期类型:标记 实际类型:[Symbol] 在'(:)'的第一个参数中,即'sym' 在表达式中:sym:(getSymbols(stmt:stmts))“任何帮助? – willrobertshaw

0

@gallais会需要我写更多的功能或可它仍然是 在一个单一的功能呢?因为我想只是一个单一的功能来解决这个问题

这是明智的要简单的解决方案,但减少了使用功能的数量是不是你如何实现与哈斯克尔这一目标。相反,要找到想要重用定义的简单解决方案。您希望将问题的解决方案看作是对较小问题的已知解决方案的组合。这让你只需记住一点就可以解决很多事情。

于是,我们开始像这样的列表:

[["A","B","C"],["D","A"],["E","B","C"]] 

,我们希望找到一个包含所有相同的字符串,没有别人,没有重复的列表。如果我们将列表与concat :: [[a]] -> [a]拼合起来怎么办?

["A","B","C","D","A","E","B","C"] 

鉴于同样的问题陈述,很明显我们会得出同样的答案。所有重要的是弦是什么;其余的结构是不相关的。

从这里我们只需要删除列表中的重复项。有几种方法可以做到这一点。效率低下的是nub :: Eq a => [a] -> [a]。更有效的方法是Set.toList . Set.fromList :: Ord a => [a] -> [a]import qualified Data.Set as Set。无论我们选择,我们的解决方案是这样的:

nub . concat 

奖励:设计一种方法删除的使用从Data.Listsort :: Ord a => [a] -> [a]重复。