2011-12-16 5 views
3

사용자 정의 유형을 표시의 인스턴스로 만들려고합니다.하스켈에서 임의의 재귀 유형에 대한 표시 정의

여기에 theType이 있습니다. 기본 Set 유형입니다.

data Set a = Insert a (Set a) | EmptySet 

나는

Insert 1 (Insert 2 (Insert 3 EmptySet)) 

과 같이 내가 이것을 어떻게

{1, 2, 3} 

처럼 표시 할? 문자열 연결을 시도했지만 문자열 보간 작업이 나쁜 형식으로 간주됩니다 (하스켈이 기본적으로 지원하지 않는 것 같습니다). 또한 목록에서 중괄호를 어떻게 얻을 수 있습니까? 지금까지 내가 요리 할 수 ​​있었다 모두가 기본적으로 아무것도 ...

instance (Show a) => Show (Set a) where 
    show EmptySet = "" 
    show (Insert a as) = show a ++ show as 

은 또한, 나는이에 구현하는 방법을 볼 수 있도록 목록 구현을 찾을 Hoogle 및 Hayoo를 사용하려고하지 않습니다 어떤이 있었다 기울기. 나는 그것을 발견 할 수 없었다. 누구든지이 포인터를 가지고 있습니까? "show :: [a] -> String", "Data.Lists", "Lists"등을 검색하려고했습니다 ...

+3

그런데 이것은 아마도 나쁜 생각 일 것입니다. 'show'의 결과는'show'에 전달 된 값과 동일한 값을 생성하는 유효한 하스켈 코드 여야합니다. 'fromList' 함수를 정의하고 집합 {1, 2, 3}에'show '를 만드는 것이 좋습니다. 'fromList [1, 2, 3]'; 이것은 표준 Data.Map 및 Data.Set 라이브러리가 취하는 접근 방식입니다. 또는,이 표기법으로 세트를보기 위해'show' 대신에 호출되는 함수를 정의 할 수 있습니다. – ehird

답변

5

직접 재귀와 해결책

그렇게해야합니다. 그래서, 시험해 봅시다 :

> show (Insert 2 (Insert 3 (Insert 5 EmptySet))) 
"{2, 3, 5}" 
+1

'(++)'의 비효율적 인 사용을 싫어한다면'show' 대신'showsPrec'을 구현해야합니다. –

+0

@SjoerdVisscher : 물론 동의합니다.하지만 첫 번째 구현으로 델타를 시연하고 싶었습니다. –

4

데이터 유형은 재귀적일 수 있지만 재귀적일 필요는 없습니다. .

import Data.List (intercalate) 

instance Show a => Show (Set a) where 
    show x = "{" ++ intercalate ", " (toList x) ++ "}" 

여기에 함수 toList :: Set a -> [a]이 있다고 가정합니다. 재귀는 거기에 숨겨져 있습니다.

리스트 구현이 Show typeclass에서 showList 기능을 통해 수행된다 (그래서 String S, 일명 S [Char]는 다르게 표시 될 수있다).

+0

나는 일종의 멍청한 행동이지만 목록에 같은 유형의 요소가 모두 포함되어 있기 때문에 이러한 상황이 발생하지 않습니까? 이 함수에 숫자 목록을 입력하면 형식 오류가 발생하지 않습니까? –

+1

정의한대로 집합에도 같은 유형의 요소가 있어야합니다. 'Insert a (Set a)'에서, 그것은 모두'a'입니다. 그래서 문제가 있어서는 안됩니다. – redxaxder

5

귀하의 유형은 여전히 ​​목록과 동형입니다. 어디서나 그 Show 인스턴스가 정의됩니다; 당신은 여전히 ​​사용할 수 있습니다 : 당신이 (++)의 비효율적 인 사용을 좋아하지 않는 경우에

instance Show a => Show (Set a) where 
    show = ('{' :) . go 
    where 
     go EmptySet   = "}" 
     go (Insert x EmptySet) = show x ++ "}" 
     go (Insert x xs)  = show x ++ ", " ++ go xs 

, 당신은 물론 사용할 수 있습니다 difference lists :

instance Show a => Show (Set a) where 
    show = ('{' :) . ($ []) . go 
    where 
     go EmptySet   = ('}' :) 
     go (Insert x EmptySet) = shows x . ('}' :) 
     go (Insert x xs)  = shows x . (", " ++) . go xs 
여기
toList (Insert a b) = a:toList b 
toList EmptySet = [] 

instance Show a => Show (Set a) where 
    show = show . toList 
관련 문제