2013-08-18 2 views
11

은 우리가 내가하는 기능을해야 할 우리가하스켈 : 문자열로 데이터 생성자의 이름을 가져옵니다

data D = X Int | Y Int Int | Z String 

있다고 가정 해 봅시다 getDConst

중 하나 "X", "Y", 또는 "을 반환
getDConst :: D -> String 

Z "를 입력에 사용 된 데이터 생성자에 따라 비교합니다. 모든 데이터 생성자에 case을 수행 할 필요없이 이것을 작성하는 일반적인 방법이 있습니까?

import Data.Data 
data D = X Int | Y Int Int deriving (Data,Typeable) 

let result = show $ toConstr (X 3) -- result contains what we wanted 

답변

13

이 솔루션 나 자신을 발견하지만, 다른 사람들을 돕기 위해이 질문을 떠나 (I 솔루션이 Data.Typeable 또는 비슷한에 의존하여 확인입니다) Show으로 수정하십시오.

getDConst :: D -> String 
getDConst = head . words . show 

Show은 게으르므로 모든 필드를 출력하지 않습니다. 당신은 ghci에이 코드를들이받은 테스트 할 수 있습니다

Prelude> data D = D [Int] deriving (Show) 
Prelude> getDConst $ D [1..] 
"D" 
+1

다른 사람이 함께 오류를 얻을 경우 추가 시도'{- # 언어 DeriveDataTypeable #을 -} '파일의 시작 부분. GHC에서 데이터 및 유형을 파생시킬 때 필요합니다. – jPlatte

6

당신이 Typeable를 사용하지 않으려면, 당신도 할 수 있습니다

+0

생성자와 관련이없는 사용자 정의 출력을 구현할 수도 있습니다. – kqr

+0

'show'는 게으르다. 그래서 이것은별로 느리지 않을 것이다. 'take 5 (show (Just undefined)) '가 잘 동작하는 것을 주목하라. –

+2

당신은'단어'가 아니라'unwords '를 의미합니다. (사실,'takeWhile (/ = ''). show'와 같은 것을 쓸 것입니다.) – Lynn