2015-01-15 3 views
3

인스턴스 메서드 구속 :내가 쓰고 싶은

{-# LANGUAGE InstanceSigs #-} 
{-# LANGUAGE DatatypeContexts #-} 

data Ord a => S a = ... 
toList :: Ord a => S a -> [a] 
fromList :: Ord a => [a] -> S a 

instance Functor S where 
    fmap :: (Ord a, Ord b) => (a -> b) -> S a -> S b 
    fmap f = fromList . fmap f . toList 

을하지만 GHC 클래스를

질문과 일치하지 않는

방법 서명을 저를 때린 유지 :

  • 해결 방법을 알고 있습니까? ?
  • 이 제한으로 어떤 문제가 해결됩니까?
+5

ghc 경고 : -XDatatypeContexts는 널리 사용되지 않으며 널리 허위로 간주되어 Haskell 언어에서 삭제되었습니다. – ErikR

+0

@ user5402 왜 그런가요? 대신 당신은 무엇을 할 것입니까? –

+2

@MichaelFox'data S와 같은 GADT, S :: Ord a => [a] -> S a' 또는 생성자가 무엇이든간에. – bheklilr

답변

5

간단히 말해서. Functor 클래스는 a -> b이 아닌 a -> b으로 모두 작동해야합니다. 그래도 자신 만의 FunctorOrd을 정의 할 수 있습니다.

class FunctorOrd f where 
    fmapOrd :: (Ord a, Ord b) => (a -> b) -> f a -> f b 

그러나 원하는 결과가 아닐 수 있습니다. 유일성을 유지하기 위해 내부적으로 바이너리 트리를 사용하는 일종의 집합과 같은 구조를 만들고 싶다고 생각합니다. 나는이 단순히 집합의 모든 Inteven을 적용 할

s :: S Int 
s = fromList [1..100] 

t :: S Bool 
t = fmap even s 

그런 짓을한다면 어떻게됩니까, 포함되어 그냥 뭐, 모든 구조를 변경 할 수 없습니다.

smap :: (Ord a, Ord b) => (a -> b) -> S a -> S b 
smap f = fromList . map f . toList 

또는 더 효율적이지만 여전히 값만이 아닌 구조 자체를 변경할 수있는 기능을 갖춘 것이 더 좋을 것입니다.

이것은 정확히 제한되어 있지 않으며 이 올바르게 작동하려면 Functor 법을 준수해야합니다. 큰 문제는 아니지만 다양한 ListT 구현의 논란이 많은 역사를 살펴보고 모나드 법을 모두 충족하지는 못합니다.