2010-04-06 3 views
3

f 함수를 값 목록에 적용하고 싶지만 함수 f이 임의로 실패 할 수도 있습니다 (실제로는 클라우드의 서비스로 호출됩니다) .목록의 모든 값에 실패 할 수있는 함수 적용

나는 map과 같은 것을 사용하고 싶다고 생각했지만 목록의 모든 요소에 함수를 적용하고 나중에 어떤 것이 실패하고 어떤 것이 성공했는지 알고 싶습니다.

은 현재 내가 오류 쌍의 기능 f의 응답 객체를 포장하고있는 나는 할 수 후 효과적으로 unzip 이후

즉, 뭔가 같은

g : (a->b) -> a -> [ b, errorBoolean]

f : a-> b

과에를 코드를 실행하십시오. map g (xs)

더 좋은 방법이 있나요? 또 다른 대안은 배열의 값을 반복 한 다음 성공적인 값을 나열한 배열과 실패를 나열한 배열을 반환하는 것입니다. 나에게 이것은 매우 일반적이어야하는 것으로 보인다. 또는 나는 특별한 가치를 되돌릴 수있다. 이 문제를 다루는 가장 좋은 방법은 무엇입니까 ?? 그렇지 않으면 Just (f x)을 반환

f: a -> b 
g: (a -> b) -> a -> Maybe b 

f가 실패 할 경우, g 반환 Nothing :

+0

FYI : Haskell의 목록은 동일해야합니다 (즉, 한 가지 유형 만 보유 할 수 있음). 귀하의 경우에는 튜플'(b, Bool)'을 반환해야합니다. 물론 적절한 방법은 Maybe 또는 Either를 사용하는 것입니다. – kennytm

답변

15

f 경우 의심 할 여지없이 일부 모나드, 아마 IO 모나드 또는 IO 모나드에서 파생 된 모나드를 사용 f보다, 클라우드로 전화를하고있다. map의 모나드 버전이 있습니다. 다음은 첫 번째 시도로, 이렇게 일반적으로 할 것입니다 :

f :: A -> IO B -- defined elsewhere 
g :: [A] -> IO [B] 
g xs = mapM f xs 
-- or, in points-free style: 
g = mapM f 

이는 gf에 대한 호출이 실패 할 경우, 어떤 값을 반환하지 실패합니다 (아마도) 바람직하지 않은 속성이 있습니다. 우리는 그것을 이렇게함으로써 고친다 f는 응답 또는 오류 메시지를 돌려 보낸다. 당신이 모든 오류가 함께 반환하고, 성공의 모두 함께 뭉쳐하려면

type Error = String 
f :: A -> IO (Either Error B) 
g :: [A] -> IO [Either Error B] 
g = mapM f 

, 당신은 Data.Either에서 leftsrights 기능을 사용할 수 있습니다. 오류 메시지가 필요하지 않은 경우

h :: [A] -> IO ([B], [Error]) 
h xs = do ys <- g xs 
      return (rights ys, lefts ys) 

, 단지 Maybe B 대신 Either Error B 사용합니다.

데이터 형식이 오류 또는 올바른 값이 될 수있는 값을 나타내는 가장 일반적인 방법입니다. 오류는 Left 생성자를 사용하고 올바른 값은 Right 생성자를 사용합니다.보너스로, "right"는 영어로 "올바른"의미이기도하지만 정확한 값이 Right 생성자를 사용하는 이유는 실제로 더 깊습니다 (이는 올바른 결과를 수정하는 양쪽 모두에서 펑터를 만들 수 있음을 의미하기 때문입니다. Left 생성자를 통해 가능하지 않음).

관련 문제