当我构建我的数据结构时,我发现了一个问题,我在解决它时遇到了问题。我的数据结构“Structure”是String和subStructures列表。
问题在于下面的“lookFor”方法,它应该在(Structure b xs)中查找名为“a”的子结构并返回它。如果不在“b”的列表(xs)上,它应该继续查看每个xs元素的列表,依此类推。如果没有找到它就什么都不做。
我的想法是递归,为此,我想“map lookFor xs”,以防它没有找到名为“a”的结构。
Ghci说“无法将预期类型结构与实际类型[结构]相匹配” 我理解,因为在所有地图返回元素列表而不是元素之后。
data Structure = Structure String [Structure]
name :: Structure -> String
name (Structure a xs) = a
subStrcts :: Structure -> [String]
subStrcts (Structure a []) = []
subStrcts (Structure a xs) = [name x | x <- xs]
lookFor :: String -> Structure -> Structure
lookFor a (Structure b xs)
| elem (elemIndex a (subStrcts (Structure b xs))) [0..] = xs !! (fromJust (elemIndex a (subStrcts (Structure b xs))))
| otherwise = map (lookFor a) xs
有什么想法吗?感谢
答案 0 :(得分:4)
可能的解决方案是:
import Control.Applicative
import Data.Foldable
data Structure = Structure String [Structure]
deriving Show
lookFor :: String -> Structure -> Maybe Structure
lookFor a s@(Structure b xs)
| a == b = Just s
| otherwise = asum (map (lookFor a) xs)
在上方,map (lookFor a) xs
在子结构中搜索a
。这会产生[Maybe Structure]
,我们使用asum
来获取第一个Just _
值,以便我们可以返回它。 (如果未找到此类值,asum
将返回Nothing
。)
如果您不想从库中利用asum
,那么定义它是一个不错的初学者练习。
答案 1 :(得分:0)
作为递归结构,您需要设置基本案例。在您的示例中,当您耗尽列表中的所有结构时会发生这种情况。
作为@WillemVanOnsem,最好返回Maybe Structure
,因为lookFor
函数可能无法找到结构
import Data.List (elemIndex)
import Data.Maybe (fromJust, isJust)
data Structure = Structure String [Structure]
name :: Structure -> String
name (Structure a xs) = a
subStrcts :: Structure -> [String]
subStrcts (Structure a []) = []
subStrcts (Structure a xs) = [name x | x <- xs]
lookFor :: String -> Structure -> Maybe Structure
lookFor a (Structure b xs)
| null xs = Nothing
| isJust maybeIndex = fmap (xs !!) maybeIndex
| otherwise = lookFor a (Structure (name (head xs)) (tail xs))
where maybeIndex = elemIndex a (subStrcts (Structure b xs))