覆盖不同数据类型的函数

pet*_*rxz 1 haskell overriding

我试图定义一个函数,我希望它的行为略有不同,具体取决于作为参数传入的数据类型、字符串和整数。人们会如何去做这件事呢?或者您是否可以建议进行任何更改以某种方式将这两个函数组合成一个函数。我读过,尝试验证数据类型不太像 haskell,所以我认为重写可能是执行此操作的方法,但编译器不喜欢重复:(

jumpTo :: Int -> [String] -> [String]
jumpTo index t = do 
    let (x,y) = splitAt index t
    init x ++ [last x ++ "QQ"] ++ y

jumpTo :: String -> [String] -> [String]
jumpTo string t = do 
    pos <- [fromJust (findWord string t)]
    let (x,y) = splitAt pos a
    init x ++ [last x ++ "QQ"] ++ y
Run Code Online (Sandbox Code Playgroud)

换句话说,我想要一个jumpTo可以传递 aStringInt作为其第一个参数的函数;如果它是一个字符串,我会在列表中找到它,对于一个整数,我会立即使用索引进行操作。使用相同的函数来执行此操作似乎更优雅。

Fyo*_*kin 5

这正是类型类背后的想法:您不是单独定义函数(或一组函数),而是将其定义为属于一个类型类,该类型类用一个(或多个)类型变量进行标记。然后,定义该类型类的一个或多个实例,并用不同的类型替换该类型变量,并为每个实例中的函数定义单独的主体。最终效果是函数根据其参数或结果的类型具有不同的主体。

在你的例子中:

class JumpTo a where
    jumpTo :: a -> [String] -> [String]

instance JumpTo Int where
    jumpTo index t = do 
        let (x,y) = splitAt index t
        init x ++ [last x ++ "QQ"] ++ y

instance JumpTo String where
    jumpTo string t = do 
        pos <- [fromJust (findWord string t)]
        let (x,y) = splitAt pos a
        init x ++ [last x ++ "QQ"] ++ y
Run Code Online (Sandbox Code Playgroud)

  • @peterxz您将需要打开“TypeSynonymInstances”和“FlexibleInstances”。完成此操作后,您编写的代码仍然无法编译,但这是一个不相关的问题。 (3认同)