2016-10-12 3 views
1

나는 연산자를 제공하는 기능을 할 노력하고있어 및 기능은 같은 목록을 통해 갈 것이다 : 처음에는하스켈 기능 목록의 합과 곱 번호

reduce (*) even [1,2,3,4,5] => 8 
reduce (+) odd [1,2,3,4,5] => 9 

나는 이런 식으로 뭔가를했다 :

reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int 
reduce op x y = foldl op 1 (filter x y) 

그리고 곱하기에는 문제가 없지만 합계를 시도 할 때 하나의 숫자가 추가되었습니다. 나는 다음과 같은 오류 받기 할 때

reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int 
reduce op x y = 
    if op == (*) then foldl op 1 (filter x y) 
     else if op == (+) then foldl op 0 (filter x y) 
      else 0 

그러나 : 그래서 나는 경우 추가 생각 (-> 지능 - 지능> INT) 식의

인스턴스의 정의에 대한 요구가 감소

정확히 무엇을 의미합니까? 어떤 아이디어? 미리 감사드립니다.

+0

당신이 숙고하는 경우 :해야'(\ XY -> X + y + 0)''(\ xy -> x + y)'와 같을까요? 그렇다면 어떤 알고리즘을 통해 이것을 결정할 것을 제안합니까? 그렇지 않다면,'reduce (\ xy -> x + y)'를'reduce (\ xy -> x + y + 0)'로 바꾸는 리팩토링에 정말로 편안합니까? - 명백하게 무해한 로컬 재 작성 - 그렇게 과격한 행동? (나는이 질문들이 답할 수 없다는 말은 아니지만 대답하는 법에 대해 신중하게 생각하면 깨달을 수있다.) –

+0

아마도 관련 질문 : [동등성을 위해 두 함수를 비교하는 방법] (http://stackoverflow.com/q/) 17045941/791604) –

답변

4

현재 가져 오기를 사용하면 함수를 평등하게 비교할 수 없다는 것을 의미합니다 (적절한 가져 오기를 사용해도 사용자가 요구하는 평등을 수행 할 수있는 좋은 방법은 없습니다).

reduce op u x y = foldl op u (filter x y) 

관심 많은 경우 이미 조작 유닛을 지정하는 Monoid 인스턴스가 :

하나의 간단한 해결책은 사용자가 이와 같이, 동작 및 장치를 모두 제공 할 것을 요구한다. 예를 들어, 거기에 SumProduct 경우, 그래서 당신이 작성하는 것이 좋습니다 다음과 같이 사용되는

reduce inject p = foldMap inject . filter p 

:

> reduce Sum even [1..5] 
Sum {getSum = 6} 
> reduce Product odd [1..5] 
Product {getProduct = 15} 
3

What does it mean exactly? Any ideas? Thanks in advance

(Int -> Int -> Int)을 다른 것으로 비교하려고합니다. 그러나 함수가 평등한지 검사 할 수는 없습니다. , 또는

reduce :: (b -> a -> b) -> (a -> Bool) -> b -> [a] -> a 
reduce op f x xs = foldl op x (filter f xs) 

을 모노 이드 및 foldMap를 사용하는 방식으로

reduce :: (Int -> Int -> Int) -> (Int -> Bool) -> Int -> [Int] -> Int 
reduce op f x xs = foldl op x (filter f xs) 

, 당신은 함수의 형태를 일반화 할 수 있습니다 대신에 초기 값을 제공합니다.