如何让这个Haskell函数进行类型检查


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) 

我们的想法是,我想申请一个函数在一个元组,但它没有类型检查因为第二个元素的元组可以IntChar

错误信息如下:

* 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)

在这种情况下不值得。

最新更新