我正在学习Haskell并试图弄清楚如何在haskell中实现“duck typing”和。所以它应该是一个函数,接受char或int,并依赖于concat或添加它。 所以函数定义看起来应该是这样的: duckplus ::(AddableUnionType a) - > a - > a - >一个
duckplus 1 "1" -- "11"
duckplus 1 1 -- 2
是否可以使用模式匹配?
答案 0 :(得分:7)
非惯用的Haskell
你可能应该把这看作是Haskells类型系统能够很好地解决的问题的演示。
对于实际工作,我不会推荐这样的解决方案。
这是一个可能的实现(使用 can of worms aka扩展):
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
class DuckSum a b where
type Result a b :: *
duckplus :: a -> b -> Result a b
instance DuckSum Int String where
type Result Int String = String
duckplus a b = show a ++ b
instance DuckSum String Int where
type Result String Int = String
duckplus a b = a ++ show b
instance DuckSum Int Int where
type Result Int Int = Int
duckplus a b = a+b
这是一个使用它的交互式会话:
λ> duckplus (1 :: Int) "1"
"11"
λ> duckplus "1" (1 :: Int)
"11"
λ> duckplus (1 :: Int) (1 :: Int)
2
注意您需要在此处输入类型注释1
可以是任何Num
- 也请谨慎使用
答案 1 :(得分:0)
也许我把问题写得不正确,但看起来,它可以更容易解决,如下所示:
data IntOrString = Mint Int | Mstr String
plus (Mint a) (Mint b) = show (a + b)
plus (Mint a) (Mstr b) = show a ++ b
plus (Mstr a) (Mint b) = a ++ show b
plus (Mstr a) (Mstr b) = a ++ b
res = plus (Mint 1) (Mint 1) -- 2
res = plus (Mstr "1") (Mint 1) -- 11
它需要将Int和String包装到构造函数值,但不需要任何外部。