data D = A Int Int | B Int Char
instance Show D where
show (A a b) = show b
show (B a b) = show b
hehe :: D -> String
hehe d = show u ++ show v
where (u, v) = show <$> case d of
A a b -> (a + 1, b)
B a b -> (a + 2, b)
我们的想法是,我想申请一个函数在一个元组,但它没有类型检查因为第二个元素的元组可以Int
或Char
。
错误信息如下:
* Couldn't match expected type `Int' with actual type `Char'
* In the expression: b
In the expression: (a + 2, b)
In a case alternative: B a b -> (a + 2, b)
|
11 | B a b -> (a + 2, b)
|
我想知道是否有一个优雅的解决方案来解决这个问题?
你可以把show推入case:
hehe :: D -> String
hehe d = show u ++ show v
where (u, v) = case d of
A a b -> (a + 1, show b)
B a b -> (a + 2, show b)
如果你真的,真的想延迟显示,那么你可以使用ExistentialQuantification
语言扩展:
data SomeShow = forall a. Show a => SomeShow a
hehe :: D -> String
hehe d = show u ++ show v
where (u, v) = ((SomeShow x) -> show x) <$> case d of
A a b -> (a + 1, SomeShow b)
B a b -> (a + 2, SomeShow b)
在这种情况下不值得。