0

私はまだHaskellに完全に精通しているわけではありませんが、自分でいくつかの演習を行っているときに、将来発生する可能性のある問題に遭遇しました。そうでない場合でも、将来的にこれを行う方法を知りたいと思います。

モジュールがあるとしましょう

module UserType where

data ThisModulesData = UserData String | ThisModulesInternal Int

moduleMethod :: (ThisModulesData -> Int) -> ThisModulesData -> Int
moduleMethod func dat = case dat of
    UserData _             -> func dat
    ThisModulesInternal i -> i

processList :: (ThisModulesData -> Int) -> [ThisModulesData] -> Int
processList func xs = sum $ map (moduleMethod func) xs

次に、このモジュールを使用したい場合は、次のようなものがあります

dataList :: [ThisModulesData]
dataList = [UserData "Type1", UserData "Type2", ThisModulesInternal 8]

processFunction :: ThisModulesData -> Int
processFunction (UserData command) = case command of
    "Type1" -> 1
    "Type2" -> 2
    _       -> 0
processFunction _ = 0

result :: Int
result = processList processFunction dataList

私がやりたいのは、文字列をもっとhaskellのようなものに置き換えることです。そうすれば、タイプセーフであり、もしあればコンパイルエラーが発生する可能性があります。

dataList = [UserData "Wrong", UserData "ThisIsWrong", ThisModulesInternal 97]

ありがとう。StackOverflowの助けを借りて、Haskellを学ぶのはかなり楽しい時間でした。

編集:

明確にするために、モジュールファイルを静的なままにして、モジュールのユーザー実装で変更が必要なこと(たとえば、「type3」を追加する場合)が発生するようにします。

4

1 に答える 1

1

タイプパラメータを使用します。

module UserType where

data ThisModulesData a = UserData a | ThisModulesInternal Int

moduleMethod :: (a -> Int) -> ThisModulesData a -> Int
moduleMethod func dat = case dat of
    UserData x            -> func x
    ThisModulesInternal i -> i

processList :: (a -> Int) -> [ThisModulesData a] -> Int
processList func xs = sum $ map (moduleMethod func) xs

その後

data Ours = Type1 | Type2
type OurData = ThisModulesData Ours

dataList :: [OurData]
dataList = [UserData Type1, UserData Type2, ThisModulesInternal 8]

processFunction :: Ours -> Int
processFunction command = case command of
    Type1 -> 1
    Type2 -> 2

result :: Int
result = processList processFunction dataList

nbの定義も変更したmoduleMethodので、たとえばprocessFunction、を気にする必要はありませんThisModulesInternal

于 2012-07-30T19:44:46.717 に答える