对于这样的输入,代码bellow非常适用:
*Main> eval 'y' (21 :: Int)
42
*Main> eval 'x' 'a'
42
*Main> eval (21 :: Int) (21 :: Int)
42
*Main> eval (42 :: Int) 'a'
42
这背后的一般问题是我想添加两件事。添加到Int
并不难实现(它已经内置)。但我有一个给定的函数(此处为geti
),它将Char
解析为Int
s而我的add
- 函数现在应该添加两个Int
以及Int
与Char
相结合(在每个排列中)。 Char
功能将geti
转换为Int
s,以便添加它们。我考虑过另一个可能的解决方案:
eval (geti 'a') (42 :: Int)
但这对我来说是不可能的。
所以一般来说我的问题是:有没有办法让这更简单或更优雅?
这是代码:
-- A static function only used to resolve some demo data
geti :: Char -> Int
geti c | c == 'x' = 42
| c == 'y' = 21
| c == 'z' = 10
| otherwise = 0
-- Here comes the problem:
class Eval t1 t2 where
eval :: t1 -> t2 -> Int
instance Eval Int Int where
eval a b = a + b
instance Eval Int Char where
eval a c = a + (geti c)
instance Eval Char Int where
eval c b = (geti c) + b
instance Eval Char Char where
eval c1 c2 = (geti c1) + (geti c2)
PS:我也尝试将here的解决方案与“通用”(是的,它的Java语言,但我是Haskell ... sry的新手)功能相结合,但这并没有工作...
答案 0 :(得分:7)
我认为为“可以转换为Int
”构建类型类并使用它来实现eval
会更直接:
class Intable a where
intify :: a -> Int
instance Intable Int where
intify = id
instance Intable Char where
intify = geti
eval :: (Intable a, Intable b) => a -> b -> Int
eval a b = intify a + intify b