簡體   English   中英

Haskell:嵌套列表理解

[英]Haskell: Nested List Comprehension

我有一份上學的任務,我需要幫助。 到目前為止,我根據賦值指令創建了兩種類型, ArgumentPredicate

在這個項目中,我必須在標題為“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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM