2014-01-26 5 views
2

임의의 함수에 문자열 목록을 "적용"할 수있는 함수를 작성하려고합니다.임의의 함수에 문자열 목록 적용

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, OverlappingInstances, TypeFamilies #-} 

class Apply a c 
    where apply :: a -> [String] -> c 

instance (Read a, Apply b c) => Apply (a -> b) c 
    where apply _ [] = error "not enough arguments" 
     apply f (x:xs) = apply (f (read x)) xs 

instance (a ~ b) => Apply a b 
    where apply f [] = f 
     apply _ (_:_) = error "too many arguments" 

예 :

g1 :: Int -> Bool 
g1 x = x > 10 

g2 :: Bool -> Int -> Int 
g2 b n = if b then 10*n else n-1 

test1 = apply g1 ["3"]    -- False 
test2 = apply g2 ["True", "33"]  -- 330 
test3 = apply g2 ["False", "0"]  -- -1 
test4 = apply g2 []     -- error "not enough arguments" 
test5 = apply g2 ["True", "3", "x"] -- error "too many arguments" 
test6 = apply (length :: [Int] -> Int) ["[4,5,6]"]   -- 3 
test7 = apply (tail :: [Char] -> [Char]) [ "['a','b','c']" ] -- "bc" 

나는 다음과 같은 것을 쓰고 싶습니다

wrap :: (Show b, Apply a b) => a -> ([String] -> String) 
wrap f xs = show $ apply f xs 

하지만 GHC과 함께 불만을 : 여기에 지금까지있어 무엇 Could not deduce (Show a0) arising from a use of 'show' ...

그러나 구체적인 정의는 다음과 같이 작동합니다.

w1 xs = show $ apply g1 xs 
w2 xs = show $ apply g2 xs 

입력 [String] -> String의 기능을 초래할 :

test8 = w1 ["20"]   -- "True" 
test9 = w2 ["False", "3" ] -- "2" 

내가 wrap 작동시킬 수있는 방법이 있나요? apply을 구현하는 더 좋은 방법이 있습니까?

답변

1
당신이 ScopedTypeVariables을 추가하고이 쓰는 경우가 작동하는 것 같다

:

wrap :: forall a b . (Show b, Apply a b) => a -> ([String] -> String) 
wrap f xs = show (apply f xs :: b) 

내가이 그것을 수정 이유를 확실히 모르겠어요 솔직히 말해서,하지만 당신은이 개 중복 인스턴스와 섬세한 영역에있어이 Apply와 나는 이것이 바로 a ~ b 인스턴스와 apply에 대한 호출을 해결 한 후 결과로 f의 유형에 대한 Show을 원하는 대신 wrap의 유형 서명에 선언 Apply 예를 건네 사용 GHC를 설득하기 위해 필요하다고 생각합니다.

4

나는이 모든 당신이 얻을 중복 인스턴스 오류와 관련된 믿는 당신은 또한

class Apply a c | a -> c 
    where apply :: a -> [String] -> c 

적용의 선언을 변경 시도 할 수 있습니다 그리고 FunctionalDependencies 확장을 추가, 현재 랩 서명

를 작동 "추론 할 수 없습니다"오류가 발생했습니다.

+0

이것은 카레 함수의 "결과"가 무엇인지에 대한 모호성을 제거하기 때문에 좋은 아이디어 인 것 같습니다. –

+0

'LANGUAGE UndecidableInstances'도 추가해야합니까? – ErikR