2009-05-17 5 views
1

// редактировать 5 , когда я использую только эти 2 линиивложенным, если в Haskell

index :: [String] -> [String] -> Bool 
    index a b = and [x `elem` a |x <- b] 

он работает отлично !!!!

например:

индекс [ "ASD", "asdd", "росы"] [ "asdd", "AsdaD"]

ложных

Но когда я использую весь код, указанный ниже

empty [] = True 
empty _ = False 

    index a b = do 
      if empty a 
       then do putStrLn "a is empty" 
         else return() 
      if empty b 
       then do putStrLn "b is empty" 
         else return() 
     where 
      index :: [String] -> [String] -> Bool 
      index a b = and [x `elem` a |x <- b] 

Theres нет выход !! и thats вопрос я получил !!

// редактировать 6

index a b = do index' 
     if empty a 
      then do putStrLn "a is empty" 
        else return() 
     if empty b 
      then do putStrLn "b is empty" 
        else return() 
    where 
     index' :: [String] -> [String] -> Bool 
     index' a b = and [x `elem` a |x <- b] 

благодаря

+0

«последней линии, которая является основной функцией программы отлично работает без вложенной, если выше»: Это не будет, 'index'' даже не тип проверки ... – porges

+0

Что касается вашего редактирования: оба фрагмента отлично работают, я не получаю ошибку «неожиданного символа». Тем не менее, вы дали двум функциям одно и то же имя, таким образом вы не можете вызывать второй «индекс» с первого. –

+0

На ваш вопрос уже был дан ответ? – Dario

ответ

0

операций ввода-вывода в Haskell являются немного трудно, потому что они нуждаются в так называемых monads Вы бы нужна специальная do -notion здесь последовательности выходов.

Написать это так:

empty [] = True 
empty _ = False 

index a b = do 
     if empty a 
      then do putStrLn "a is empty" 
      else return() 
     if empty b 
      then do putStrLn "b is empty" 
      else return() 

Или Может быть, вы могли бы просто вернуть строки и использовать putStrLn отдельно. Вы, index', должны возвращать логическое значение, когда оно должно использоваться как условие if!

+0

Что в этом плохого? – Dario

+0

спасибо, что он отлично работал! – pier

+0

Здесь вам не понадобится синтаксис 'do', если вы удалите все' do ', ваш код все равно будет работать. –

0
index a b = if index' [] bs 
         then putStrLn "a is empty" 
         if index' a []   
         then putStrLn "b is empty" 
         else     
    where 
     index' :: [String] -> [String] -> [Int] 
     index' a b = index' True [(elem x b) | x <- a] 

Если вы сделаете это заявление таким же, вы увидите, что первый, если не имеет соответствующего предложения else.

Кроме того, предложение else ничего не возвращает - функция должна иметь возвращаемое значение при любых обстоятельствах.

2

A if Конструкция в Haskell - это выражение. Это означает, что он всегда должен оценивать значение, поэтому часть else является обязательной.

Кроме того, первая часть if должна быть логической, так что вы не можете назвать index' там, так что возвращает [Int], не Bool.

Я бы сказал, начать с чем-то вроде этого:

if isEmpty a 
then putStrLn "a is empty" 
else if isEmpty b 
    then putStrLn "b is empty" 
    else putStrLn "neither are empty" 
+0

хорошо, хорошо я попробовал это так и я все еще получаю ошибку, как «ошибка синтаксиса в выражении (неожиданный'}», возможно, из-за плохой планировки) » индекс, как бс = если IsEmpty в \t \t \t затем putStrLn "а не пуст" \t \t \t еще если IsEmpty бс \t \t \t \t затем putStrLn "б пусто" \t \t \t \t еще putStrLn "ни пустые" \t где \t \t index ':: [String] -> [String] -> [Int] \t \t index' as bs = index 'True [(elem a bs) | a <- as] – pier

+0

Вам понадобится 'do' для последовательности выходов. – Dario

+1

Чем скорее у вас проблемы с макетом. Убедитесь, что слова 'then' и' else' имеют отступы, по крайней мере, до уровня ключевого слова 'if'. В вашем текущем вопросе 'else' имеет отступ с ошибкой. Кроме того, убедитесь, что вы используете только пробелы для макета, вкладки будут испорчены. –

4

Это немного не по теме, так как, возможно, вы пытаетесь изучить правила размещения и как гнездо сослагательного наклонения, но код, который вы показать в в редакции 6 используется только if для проверки ошибок. Я бы просто выполнил проверку ошибок с помощью сопоставления с образцом вместо if.

index [] _ = putStrLn "a is empty" 
index _ [] = putStrLn "b is empty" 
index a b = putStrLn (show index') 
    where index' = and [x `elem` a | x <- b] 

(Вам не нужно return() после putStrLn, потому что он уже возвращается () для вас.)

соответствие шаблона намного проще, чтобы получить права, так как он не требует много отступов и т.д.


Edit:

Я изменил определение index' немного от ваших , В моей версии это локальная переменная вместо локальной функции. В Haskell нет большой разницы, просто index' использует a и b из окружающей среды index, поэтому ему не нужно брать параметры. (По общему признанию, index' не является таким хорошим именем для переменной.)

Также я остановился на аннотации типа, потому что я обычно не пишу их. Но они полезны, когда что-то не работает. Вот то, что это будет выглядеть следующим образом:

where index' :: Bool 
      index' = and [x `elem` a | x <- b] 
+0

короткий и не нужно беспокоиться об идентификации. спасибо – pier

+0

Почему мне не нужно определять тип index ':: [String] -> [String] -> Bool – pier

+0

Компилятор обычно может автоматически выводить типы, поэтому вам не нужно декларировать их вручную, если вы не хотите. Но обычно лучше объявить их, потому что это помогает найти проблемный код в случае ошибок типа. В этом случае вы можете объявить тип индекса как «[String] -> [String] -> IO()» или, в более общем смысле, как «(Eq a) => [a] -> [a] -> IO() ». – sth

 Смежные вопросы

  • Нет связанных вопросов^_^