2010-02-27 6 views
2

하스켈에서리스트 comprehension을 동적으로 빌드하는 것이 가능한지 궁금합니다. 나는 다음과 같은 경우 예를 들어하스켈에서리스트 comprehension을 동적으로 빌드하십시오.

:

all_pows (a,a') (b,b') = [ a^y * b^z | y <- take a' [0..], z <- take b' [0..] ] 

나는 내가 무엇을 얻을 그러나

*Main> List.sort $ all_pows (2,3) (5,3) 
[1,2,4,5,10,20,25,50,100] 

후, 내가 좋아 정말 줄은

뭔가를하는 것입니다
all_pows [(Int,Int)] -> [Integer] 

따라서 N 인수 쌍을 지원하지 않고를 지원할 수 있습니다.버전은 all_pows입니다. 나는 아직도 하스켈에게 아주 새롭기 때문에 나는 명백한 것을 간과 한 것 같다. 이것은 가능한가?

답변

11

목록 모나드의 마법 :

 
ghci> let powers (a, b) = [a^n | n <- [0 .. b-1]] 
ghci> powers (2, 3) 
[1,2,4] 
ghci> map powers [(2, 3), (5, 3)] 
[[1,2,4],[1,5,25]] 
ghci> sequence it 
[[1,1],[1,5],[1,25],[2,1],[2,5],[2,25],[4,1],[4,5],[4,25]] 
ghci> mapM powers [(2, 3), (5, 3)] 
[[1,1],[1,5],[1,25],[2,1],[2,5],[2,25],[4,1],[4,5],[4,25]] 
ghci> map product it 
[1,5,25,2,10,50,4,20,100] 
ghci> let allPowers list = map product $ mapM powers list 
ghci> allPowers [(2, 3), (5, 3)] 
[1,5,25,2,10,50,4,20,100] 

이것은 아마도 조금 더 설명을 가치가있다.

당신은 당신의 자신의

cartesianProduct :: [[a]] -> [[a]] 
cartesianProduct [] = [[]] 
cartesianProduct (list:lists) 
    = [ (x:xs) | x <- list, xs <- cartesianProduct lists ] 

등이 cartesianProduct [[1],[2,3],[4,5,6]][[1,2,4],[1,2,5],[1,2,6],[1,3,4],[1,3,5],[1,3,6]]을 쓸 수 있었다.

그러나, comprehensionsmonads은 의도적으로 유사합니다. 표준 서곡은 sequence :: Monad m => [m a] -> m [a]이고, m이 목록 모나드 [] 일 때 실제로 위에 서술 한 내용을 실제로 수행합니다.

mapM :: Monad m => (a -> m b) -> [a] -> m [b]sequencemap의 단순한 구성입니다.

각 기본의 다양한 출력의 각 내부 목록에 단일 기본 숫자를 곱하고 싶습니다. 당신이 쓸 수 재귀

product list = product' 1 list 
    where product' accum [] = accum 
     product' accum (x:xs) 
      = let accum' = accum * x 
      in accum' `seq` product' accum' xs 

또는 배

import Data.List 
product list = foldl' (*) 1 list 

실제로, product :: Num a => [a] -> a가 이미 정의되어 사용! 나는이 언어를 좋아한다. ☺☺☺

+0

'let powers (a, b) = [a^n | n <- [0 .. b-1]] ' – Tordek

+0

@ Tordek 고마워, 원래 너무 빨리 건너 뜁니다. – ephemient

+0

아름다운, 고마워. – ezpz

관련 문제