2017-12-10 26 views
1

난 그냥 몇 가지 하스켈을 배우고 및 REPL에서 지능형리스트와 함께 재생하는 동안 나는 튜플 ("bird", 4) 다음 코드에서 생성되는 방법을 이해 할 수 없습니다하스켈 : 지능형리스트 평가에 예기치 않은 결과

*Main> :{ 
*Main| [(x, y) | x <- ["cat", "dog", "bird"] 
*Main|   , y <- [1..length x]] 
*Main| :} 
[("cat",1),("cat",2),("cat",3),("dog",1),("dog",2),("dog",3),("bird",1),("bird",2),("bird",3),("bird",4)] 
내 이해로

x의 길이가 3보다 결코 더 큰, 나는 그들이 cat 세와 dog 세를 그대로 bird 세 튜플을 볼 것으로 예상한다.

왜 이런 일이 발생합니까? 하스켈은 무엇을보고 있습니까?

+3

'x'가''bird "'이면 '길이 x'는'4'입니다 (bird는 4자를 갖기 때문에). –

+0

오! 나는 그것을 얻는다.'x'는 전체 목록이 아닌 각 요소를 참조한다! 나는 그것을 완전히 오해했다. –

+0

'x'는 * loop 변수 *로 표시해야합니다 (명령형으로 작성한 경우). 실제로'x'는 개별 항목을 나타내며 * 문자열 목록은 아닙니다. –

답변

1

짧은 답변 : x항목을 값 목록의, 하지 목록 자체를합니다.

이 파이썬에서 이루어집니다처럼 당신은 하스켈에서 지능형리스트를 볼 수 있습니다

는 :

[(x, y) | x <- ["cat", "dog", "bird"] 
     , y <- [1..length x]] 

에 해당합니다 : 그래서

result = [] 
for x in ["cat", "dog", "bird"]: 
    for y in range(1, 1+len(x)): 
     result.append((x,y)) 

:

[(x,y) for x in ["cat", "dog", "bird"] for y in range(1, 1+len(x))] 

아니면 precedural 방법으로

목록 ["cat", "dog", "bird"]에 대해 x으로 반복 한 다음 모든 값에 대해 x 일 경우 range(1, 1+len(x))y으로 반복합니다. 목록의 마지막 항목은 length/ len"bird" 인 것을 의미합니다 (새는 4 자로 된 단어이기 때문에) "bird"에 해당합니다. 따라서 y은 새에 대해 네 번 반복됩니다.

경우

당신이 x의 길이의 minimum을 먹고 싶어, 당신은 사용할 수 있습니다

[(x, y) | x <- ["cat", "dog", "bird"] 
     , y <- [1..minimum (map length) ["cat", "dog", "bird"]]] 

을 경우 당신은 자체가, 당신은 그 length를 사용할 수있는 문자열 목록의 length을 먹고 싶어 목록 : so

[(x, y) | x <- ["cat", "dog", "bird"] 
     , y <- [1..length ["cat", "dog", "bird"]]]