2014-10-29 1 views
3

У меня есть задание для школы, в котором мне нужна помощь. До сих пор я создал два типа: Argument и Predicate, в соответствии с инструкциями по назначению.Haskell: Вложенный список Понимание

В этом проекте мне нужно создать список под названием «контекст» аргументов (или объектов) в мире и список фактов об этих объектах в списке под названием «факты».

Так, например, список контекста имеет аргументы «Джон» и «Бостон», а затем в нашем списке фактов мы можем создать предикат с функцией fly иметь факт «ужение джон to_boston», где to означает, что Джон летит в Бостон.

Для окончательного этапа проекта мы должны быть в состоянии спросить Haskell: «qWhere fly john», и Haskell ищет контекстный список для «john» и использует его для поиска списка фактов для «fly», и «john», чтобы в конечном итоге вернуть «to_boston» или «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)] 
+0

Можете ли вы привести конкретный пример того, как следует обращаться к 'qWhere'? Например. 'qWhere fly boston = ???'. – ErikR

ответ

1

Я не думаю, что вам нужно/хотят вложенный список понимания. Сначала вам нужно понять, что list comprehension действительно просто синтаксический сахар.

Но мы можем использовать синтаксис 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.