[英]Haskell data structure find method
在構建數據結構時,我發現一個問題,無法解決。 我的數據結構“ Structure”是String和子結構列表。
問題出在下面的“ lookFor”方法中,該方法應該在(Structure b xs)中查找名為“ a”的subStructure並將其返回。 如果不在“ b”的列表(xs)上,則應繼續查找每個xs元素的列表,依此類推。 如果找不到,它什么也不做。
我的想法是遞歸,為此,我想到了“ map lookFor xs”,以防找不到名為“ a”的結構。
Ghci說“我無法理解預期類型的結構與實際類型[結構]”,因為畢竟map返回的是元素列表而不是元素。
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
有任何想法嗎? 謝謝
可能的解決方案是:
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
,定義它是一個不錯的初學者練習。
作為遞歸結構,您需要設置一個基本案例。 在您的示例中,當您用盡列表中的所有結構時,就會發生這種情況。
與@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))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.