Haskell数据结构查找方法

时间:2017-11-22 11:26:51

标签: haskell data-structures

当我构建我的数据结构时,我发现了一个问题,我在解决它时遇到了问题。我的数据结构“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

有什么想法吗?感谢

2 个答案:

答案 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))