목록

2

내가 그런목록

data A = A { a:: String } deriving (Show) 
data B = B { b:: String } deriving (Show) 

어떤 종류의 클래스로, 레코드 집합을 말해봐

class Foo a where 
    foo :: a -> IO() 

instance Foo A where 
    foo c = ... 

그리고 나는 또한

bar = do 
    push (A {a="x"}) 
    push (B {b="y"}) 
그런 짓을 할

그리고 이런 일들이 나중에 실행될 수있는 어딘가에있는 목록으로 끝나도록

map foo l 

래퍼 유형을 생성하고 인스턴스가 파생되도록 템플릿 haskell을 작성해야 목록이 래퍼 유형이 될 수 있습니까? 이것에 대해 더 지혜로운 방법이 있습니까? 나는 솔직히 haskell 타입 시스템에 의해 꽤 고정되어 있다고 느끼고 있고, 이것을하기위한 더 좋은 방법이 있어야한다는 것을 알고있다.

답변

15

실존 적 계량으로이를 수행하는 방법이 있지만 과도한 경우가 많습니다. 더 많은 Haskell-y 접근법은 단순히 foo을 적용하고 [IO()] 결과 작업 목록을 유지하는 것입니다. 그런 다음 sequence 나중에 실행할 수 있습니다.

+3

도 참조 [자주 묻는 질문 항목 (http://www.haskell.org/haskellwiki/FAQ#I.27m_making_an_RPG._Should_I_define_a_type_for_each_kind_of_monster.2C_and_a_type_class_for_them.3F)이에, 그리고 [이에 링크 기사 (http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/). – shachaf

+2

그래서'stuffToDo = [foo A, foo B]'또는'stuffToDo = foo A >> foo B'로'stuffToDo :: IO()'에 의해 정의 된'thingsToDo :: [IO()]' – AndrewC

2

예를 들어 Existential을 사용하지만, 실제로는 사용하지 말고 hammar가 말한 것을 제안합니다.

{-# LANGUAGE ExistentialQuantification #-} 
data A = A String deriving Show 
data B = B String deriving Show 

class Foo a where 
    foo :: a -> IO() 

instance Foo A where 
    foo c = putStrLn $ "FOOA " ++ show c 

instance Foo B where 
    foo c = putStrLn $ "FOOB " ++ show c 

data Wrap = forall a . Foo a => Wrap a 

instance Foo Wrap where 
    foo (Wrap c) = foo c 

bar :: [Wrap] 
bar = [Wrap $ A "x", Wrap $ B "y"] 

main = mapM_ foo bar