2011-05-30 4 views
3
sum1::[Int]->[Int] 
sum1 [] =0 
sum1 (x:xs) = [x|x<-xs,x `mod` 2 ==0] 

Мне нужно возвращать числа, которые делятся на 2, когда список предоставляется, но приведенный выше код дает мне эту ошибку компиляции:Haskell список понимание

Instance of Num [Int] required for definition of sum1 

также объяснить, что (x:xs). Это «X элемент xs список? '

Если мы хотим получить n-й элемент списка, как мы его получим?

ответ

15

Вы задали несколько вопросов, поэтому я отвечу им один за другим.

Вопрос 1: почему компилятор мне сказал Instance of Num [Int] required for definition of sum1?

Вы создали функцию под названием sum1 с типом [Int]->[Int]. Однако рассмотрим строку sum1 [] = 0: это возвращает Int, а не [Int]. Решение этой проблемы состоит в том, чтобы изменить линию на sum1 [] = [].

Вопрос 2: что означает (x:xs)?

Haskell позволяет вам выполнить что-то, что называется pattern matching. Не вдаваясь в подробности, так как есть много лучших объяснений, эффект заключается в том, что x - это первый элемент списка, а xs - это остальная часть списка, то есть вы очистили первый элемент список.

Например, если вы назвали sum1 [1,2,3], x будет 1 и xs будет [2,3].

Вопрос 3: если мы хотим получить n-й элемент списка, как его получить?

Обычный способ сделать это, чтобы использовать !! функцию - которая инфиксальный, то есть, вы обеспечиваете как левый и правый аргумент так же, как вы бы для + или *. Например, [1,2,3]!!1 вернет 2.


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

+0

благодаря его решаемому всему Probs :) – Sudantha

+0

благодарственного oftz за то, что выглядит довольно :-) Я одобряю вашу правку. – erisco

+0

+1 хорошие простые ответы на каждый заданный вопрос. –

1
sum1::[Int]->[Int] 
sum1 [] = [0] // problem here 
sum1 (x:xs) = [x| x <- xs ,x `mod` 2 == 0] 

sum1 должен вернуть [Int], но в этом случае она возвращается только Int.

Образец, соответствующий списку с (x:xs), поместит первый элемент списка в x, а остальная часть списка - в xs.

Если вы хотите sum1 вернуть все четные числа из списка условия, что вы должны изменить свой код

sum1::[Int]->[Int] 
sum1 [] = [0] // problem here 
sum1 xs = [x| x <- xs ,x `mod` 2 == 0] 

Потому что, ваш текущий код будет пропускать первый элемент списка. Попробуйте с [2..10] в качестве входных данных. Вы не увидите 2 в списке результатов.

Чтобы получить n-й элемент из синтаксиса Haskell список xs является

xs !! n 

Пример

*Main> [1..10] !! 5 
6 

В следующий раз попадешь в беду см Some Common (and not so common!) Hugs Errors.

1

Ну, они ответили правильно вас, но в любом случае я собираюсь рассказать вам кое-что они не делали: P

Question 2: what does (x:xs) mean?

списки в Haskell сделаны: ГОЛОВЫ + TAIL, где голова первый элемент и TAIL - другие.

"head [1,2,3]" will return 1

"tail [1,2,3]" will return [2,3]

Но есть еще функции в любом случае:

"init [1,2,3] will return [1,2] "last [1,2,3] will return 3

Если вы начинаете на Haskell, проверьте this

PS: Извините за мой плохой английский!

1

Вам не нужен anker, используя понимание списка!

sum1 = \xs -> [ x | x <- xs, mod x 2 == 0] 

Другим решением для п-го элемента вопроса о:

nth_elem = \n xs -> head $ [ x | (id,x) <- zip [1..] xs, id == n ] 
Смежные вопросы