[英]Haskell: Nested List Comprehension
我有一份上學的任務,我需要幫助。 到目前為止,我根據賦值指令創建了兩種類型, Argument
和Predicate
。
在這個項目中,我必須在標題為“fact”的列表中創建一個名為“context”的列表,其中包含世界中的參數(或對象)以及關於這些對象的事實列表。
所以,舉例來說,上下文列表中有爭論“約翰”和“波士頓”,然后在我們的事實列表中,我們可以創建功能的謂詞fly
有一個事實,“飛約翰to_boston”里to
表示約翰飛往波士頓。
對於項目的最后一步,我們必須能夠問Haskell:“qWhere fly john”並讓Haskell搜索“john”的上下文列表並使用它來搜索“fly”和“john”的事實列表為了最終回歸“to_boston”或“波士頓”。
我知道這是嵌套列表理解,但是我不明白如何讓Haskell在“飛行約翰”之后返回“to_boston”。 我將在下面包含一些代碼(滾動到底部,我正在處理的內容):
{-# LANGUAGE MultiParamTypeClasses #-}
-- GL TYPES
data Type = HUMN | -- human
ANIM | -- animate
ORGN | -- organic
ORGZ | -- organization
PHYS | -- physical object
ARTF | -- artifact
EVNT | -- event
PROP | -- proposition
INFO | -- information
SENS | -- sensation
LOCA | -- location
TIME | -- time period
ATTD | -- attitude
EMOT | -- emotion
PPTY | -- property
OBLG | -- obligation
RULE -- rule
deriving (Show, Eq, Enum)
-- CUSTOM DATA TYPES
data Argument = Argument { ttype :: Type, value :: String }
deriving (Show, Eq)
data Predicate = Predicate { lemma :: String
, arguments :: [Argument] }
deriving (Show, Eq)
type Context = [Argument]
-- CREATE SEMANTICALLY TYPED ARGUMENTS AS FOLLOWS
date :: String -> Argument
date s = Argument { ttype = TIME, value = s }
time :: String -> Argument
time s = Argument { ttype = TIME, value = s }
location :: String -> Argument
location s = Argument { ttype = LOCA, value = s }
human :: String -> Argument
human s = Argument { ttype = HUMN, value = s }
phys :: String -> Argument
phys s = Argument { ttype = PHYS, value = s }
artifact :: String -> Argument
artifact s = Argument { ttype = ARTF, value = s }
animate :: String -> Argument
animate s = Argument { ttype = ANIM, value = s }
-- CREATE ENTITIES/PPs AS FOLLOWS
may15 = date "May 15, 2014"
sevenAM = time "7:00"
sandiego = location "San Diego"
john = human "John"
mary = human "Mary"
boston = location "Boston"
ball = phys "ball"
car = artifact "car"
cat = animate "cat"
mouse = animate "mouse"
to_boston = to boston
context = [
may15,
sevenAM,
sandiego,
john,
mary,
boston,
ball,
cat,
mouse
]
-- HELPER FUNCTIONS
getValue :: Argument -> String
getValue c = value c
getType :: Argument -> Type
getType c = ttype c
isType :: Argument -> Type -> Bool
isType c t = (ttype c == t)
-- CREATE PREPOSITIONS AS FOLLOWS
to :: Argument -> Predicate
to x = Predicate { lemma = "to", arguments = [x] }
-- CREATE VERBS AS FOLLOWS
class Fly a b where
fly :: a -> b -> Predicate
instance Fly Argument Argument where
fly x y = Predicate { lemma = "fly", arguments = [x, y] }
--overwrite lemma,
instance Fly Argument Predicate where
fly x y = Predicate { lemma = lemma y
, arguments = [x, arguments y !! 0] }
facts = [fly john to_boston, fly mary to_boston]
-- THIS IS WHERE I'M STUCK\/
qWhere :: (Argument -> Argument -> Predicate) -> Argument
-> [[Argument]]
qWhere f x = [[arguments z | ]| z <- facts, x `elem` (arguments z)]
-- THIS RETURNS THE ENTIRE STATEMENT:
qWhere f x = [[arguments z | ]| z <- facts, x `elem` (arguments z)]
我認為你不需要/想要嵌套列表理解。 首先,您需要了解列表理解實際上只是語法糖。
但是我們可以let ... in
語法中使用let ... in
來使用多個列表推導。 解決方案可能如下所示:
qWhere :: (Argument -> Argument -> Predicate)
-> Argument
-> [[Argument]]
qWhere f x = case find (== x) context of
Just e ->
-- first we get all facts about e.g. john
let personFacts = [z | z <- facts, e `elem` arguments z]
-- then we get all facts when we apply f to john and
-- any other arguments that exist in john
actionFacts = fmap (f e) (concatMap arguments personFacts)
-- and extract all arguments of those facts
actionArgs = concatMap arguments actionFacts
-- and can finally build the actual list of facts,
-- reduced by checking if the argument "john" is in one of our
-- actionArgs where we applied f to
in map arguments [z | z <- personFacts, e `elem` actionArgs]
Nothing -> []
您可能需要import Data.List
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.