假设我正在创建一个处理文本文件的数据管道。我有以下类型和功能:
data A = A deriving (Show, Typeable)
data B = B deriving (Show, Typeable)
data C = C deriving (Show, Typeable)
data D = D deriving (Show, Typeable)
step1 :: A -> B
step2 :: B -> C
step3 :: C -> D
对于下面的每个函数 step{1..3},我希望能够从现有文件生成一个新文件,执行如下操作:
interact (lines . map (show . step . read) . unlines)
然后我希望能够将它们排列成一个图形(因此函数可以有多个输入)以实现以下目标:
我可以遍历数据结构来判断哪些函数向哪些其他函数提供输入
数据结构将在编译时进行类型检查,因此任何无效的排列都会引发类型错误。
我知道如何在没有 2 的情况下执行 1(给他们一个通用的类型类),并且我知道如何在没有 1 的情况下执行 2(只需使用 (.)),但我不确定如何同时执行这两项操作。有任何想法吗?TIA。
更新
AndrewC 的答案非常准确,并且让我大部分时间都在那里,因为我可以使用 Map 构建元数据(名称)图并同时单独对其进行类型检查,但是我还需要一些灵活的多态性。下面的示例解决了这个问题,但有两个严重的警告:
- 在第 4 步中,我不会被迫详尽地进行模式匹配。
- 这很乏味;可能有几十个这样的“BorC”风格的多态类型,除了启用多态之外什么都不做,甚至不是很安全(见 1)。我试图对类型类的成员进行模式匹配(带有and
Step4Input
的实例),但这不起作用(它说)。B
C
Couldn't match type B with C
data BorC = ItsB B | ItsC C
step4 :: BorC -> D
step4 x = case x of { ItsB b -> D; ItsC c -> D }
-- step1 step2
-- \ /
-- ItsB ItsC
-- \ /
-- step4