예 : list = [1,2,3,4]
. listProduct list
은 [1,2,3,4,6,8,9,12,16]
을 반환합니다. 즉 [(1*1),(1*2),(1*3),(1*4),(2*3),(2*4),(3*3),(3*4),(4*4)]
목록의 요소에 다른 모든 요소를 곱하면 어떻게됩니까?
나는이 일을보고 기억하지만 더 이상 그 자원을 찾을 수 없습니다. 당신은 지능형리스트 사용하여 간단한 방법으로이 쓸 수
예 : list = [1,2,3,4]
. listProduct list
은 [1,2,3,4,6,8,9,12,16]
을 반환합니다. 즉 [(1*1),(1*2),(1*3),(1*4),(2*3),(2*4),(3*3),(3*4),(4*4)]
목록의 요소에 다른 모든 요소를 곱하면 어떻게됩니까?
나는이 일을보고 기억하지만 더 이상 그 자원을 찾을 수 없습니다. 당신은 지능형리스트 사용하여 간단한 방법으로이 쓸 수
결과에 2*2
이 포함되지 않은 이유는 무엇입니까?
당신이 중복 싶어하는 경우 경우가 --- 다음 --- --- 즉, 당신이 중복 싶지 않은 반면에
listProduct xs = nub [x * y | x <- xs, y <- xs]
1*4
같은 때문에이 있다면
triangularAutoZipWith
을 사용할 수있는 다음 --- 결과에
listProduct' xs = triangularAutoZipWith (*)
triangularAutoZipWith op = concatMap f . tails
where f [] = []
f xs @ (x : _) = map (op x) xs
을 중복 목록의 각 연속 번호로 각 숫자를 곱하고, 포함 할 당신이있는 경우 중복으로
listProduct = nub . triangularAutoZipWith (*)
Thanks. 나는 너를 사용하지 않으려 고했다. 그것은 중뇌가 심각한 성적 반향을 일으키는 것처럼 보입니다. 이것이 효과가 있지만. – ryanmehta
:
import Control.Monad
listProduct = join $ liftM2 (*)
(listProduct xs = liftM2 (*) xs xs
에 해당)
listProduct xs = [x * y | x <- xs, y <- xs]
, 그것은리스트 모나드를 사용하는 것이 더 관용적이다
이 버전을 이해하려면 (liftM2 (,)
은 데카르트 제품 자체).
listProduct xs = concatMap (\x -> map (x *) xs) xs
(당신이 기술적으로하지 않습니다 :
liftM2 f mx my = do { x <- mx; y <- my; return (f x y) }
-- expand the do notation
liftM2 f mx my = mx >>= (\x -> my >>= (\y -> return (f x y)))
-- substitute the list monad's definition of (>>=)
liftM2 f mx my = concatMap (\x -> concatMap (\y -> [f x y]) my) mx
-- simplify
liftM2 f mx my = concatMap (\x -> map (\y -> f x y) my) mx
-- simplify again
liftM2 f mx my = concatMap (\x -> map (f x) my) mx
그래서 listProduct
의 모나드 정의로 확장 : 그것은 당신이 목록 모나드에 liftM2
의 정의를 전문으로하는 경우이 어떻게 작동하는지보기 위해 쉽게 여기에 전체 목록 모나드가 필요합니다. 목록의 경우 Applicative
인스턴스가 필요하고 listProduct = join $ liftA2 (*)
도 작동하지만 모나드 정의와 함께 작동하는 방법을 표시하는 것이 더 쉽습니다. 목록의 Applicative
인스턴스는 다음과 같이 정의됩니다. Monad
인스턴스)
사용 ...
import Control.Applicative
...
listProduct list = (*) <$> list <*> list
... 그리고없이 ...
listProduct list = concat (mul <$> list <*> list) where
mul a b | a <= b = [a*b]
| otherwise = []
루브 - 골드버그 - 분위기, 당신은 사용할 수 ...
listProduct list = concat $ zipWith (map.(*)) list (map ((`filter` list).(<=)) list)
... 또는 간단하게 ...
import Data.List
listProduct list = concat $ zipWith (map.(*)) list $ tails list
[편집]
또 다른 방법은 sequence
을 사용하는 것입니다.
listProduct = map product . sequence . replicate 2
없이 : 중복으로
listProduct = map product . filter(\[a,b] -> a <= b) . sequence . replicate 2
글쎄, 당신은 이미 몇 가지 답변을 있어요,하지만 난 이전의 것들을 생각하기 때문에 모두 정확하면서 내에서 던져거야 도움이 될 수 없습니다.
당신이 이해하는 초보자 왔 가장 쉬운 솔루션은 지능형리스트입니다 :
example1 = [ x*y | x <- list, y <- list ]
이 구문은 파이썬 같은 일부 인기있는 언어로 존재하며, 어떤 경우에 쉽게 이해할 수 있어야합니다 "는 요소가 x*y
의 결과 인 목록의 경우 이 list
및 y
의 요소 인 경우 목록의 요소는 list
입니다.
example2 = [ x*y | x <- list, y <- list, x /= y ]
더 복잡한 대답은 지능형리스트가 동등하다는 사실과해야 할 : 당신은 또한 어디에 x == y
당신이 제품을 원하지 않는 경우, 예를 들어, 일부 조합을 필터링 지능형리스트에 조건을 추가 할 수 있습니다 목록 모나드; 목록 유형에 대한 표준 형식 인 Monad
의 구현. 이 example1
는 이러한 방식으로 구현 될 수 있다는 것을 의미한다 :
example1' = do x <- list
y <- list
return (x*y)
do
표기법이 단지 문법 설탕입니다 :
example1'' = list >>= (\x -> list >>= (\y -> return (x*y)))
당신이하지 않은 경우 귀하의 목록 이해력에있는 어떤 조건을 사용하여, 그냥 데카르트 제품, 당신은 떨어져 보다는 약한 Applicative
유형 클래스를 사용하여 얻을 수 있습니다.
결과에 '2 * 2'가 포함되지 않은 이유는 무엇입니까? 아마도 당신은 중복을 원하지 않을 것입니다. 그런데 왜 당신의 예제는 결과에'3 * 3'을 포함하지 않는 걸까요? – dave4420
그건 오타되었습니다, 고마워요! 업데이트되었습니다. – ryanmehta