2013-08-18 31 views
11

bize bir fonksiyonunu sahip olmak isteyen bizHaskell: dize olarak veri yapıcı adı alın

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

var diyelim getDConst

ya "X", "Y" veya "döndürür
getDConst :: D -> String 

Z ", girdisi için kullanılan veri yapıcısına göre. Her veri kurucuda case yapmak zorunda kalmadan bunu yazmanın genel bir yolu var mı?

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

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

cevap

13

çözeltisini kendim buldum, ama başkalarına yardım etmek için bu soruyu bırakarak (I çözümler Data.Typeable veya benzer bir şey güvenerek ile Tamam değilim) Bunu Show ile yapın. o tembel olduğu için

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

Show değil, çıkış tüm alanları olacak. Sen ghci Bu kodu koşuyoruz test edebilirsiniz:

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

başkasının da bu konuda bir hata alırsa: eklemeyi deneyin '{- # DİL DeriveDataTypeable # -}' senin Dosyanın başına. Verileri ve Türetilebilir olduğunuzda GHC'de gereklidir. – jPlatte

6

Eğer Typeable kullanmak istemiyorsanız, ayrıca:

+0

Ayrıca, kurucu içermeyen özel bir show çıkışı da uygulamak isteyebilirsiniz. – kqr

+0

'show' tembel, bu yüzden muhtemelen çok yavaş olmayacak. '5 (show (Just undefined))' ın nasıl çalıştığını dikkat edin. –

+2

Yani 'unwords' kelimelerini değil. (Aslında, 'takeWhile (/ =' '). Show' gibi bir şey yazardım) – Lynn