如何在Haskell中声明可接受2或3个参数的函数作为参数?
在Haskell中让函数兼容不同参数个数的传入方案
在Haskell里,所有函数本质都是柯里化的单参数函数——所谓的“双参数函数”a -> b -> c,其实是接受a后返回另一个单参数函数b -> c的语法糖。要让repetir同时支持单参数和双参数函数作为输入,有两种实用方案:
方案一:多态类型签名重载
通过为repetir定义多个类型签名,共享核心的重复逻辑,分别适配不同参数个数的函数。
首先实现处理自函数(输入输出类型一致的单参数函数)的核心逻辑:
-- 辅助函数:将自函数重复执行n次 repetirSelf :: (a -> a) -> Int -> a -> a repetirSelf _ 0 x = x repetirSelf f n x = repetirSelf f (n-1) (f x)
然后为repetir定义两个类型签名:
-- 适配单参数自函数(如 f :: a -> a) repetir :: (a -> a) -> Int -> a -> a repetir = repetirSelf -- 适配双参数函数(如 f :: b -> a -> a,接受b后返回自函数) repetir :: (b -> a -> a) -> Int -> b -> a -> a repetir f n b = repetirSelf (f b) n
使用示例
- 针对单参数自函数(比如一个修改坐标的函数):
desplazarX :: (Int, Int) -> (Int, Int) desplazarX (x, y) = (x+1, y) repetir desplazarX 3 (0,0) -- 结果为 (3,0) - 针对你的双参数函数
sacar:repetir sacar 2 miBolita miTablero -- 重复执行两次sacar操作在miTablero上
方案二:用类型类抽象可重复行为
如果需要支持更多参数个数的函数,类型类会更灵活。它可以统一描述“能够被重复执行的函数”:
class Repetible f where repetir :: f -> Int -> f -- 自函数的实例:重复执行即函数组合n次 instance Repetible (a -> a) where repetir f 0 = id repetir f n = f . repetir f (n-1) -- 双参数函数的实例:固定第一个参数后转为自函数再重复 instance Repetible (b -> a -> a) where repetir f n = \b -> repetir (f b) n
使用示例
-- 单参数自函数场景 let doblar x = x * 2 (repetir doblar 3) 5 -- 结果为40 -- 双参数函数场景 (repetir sacar 2) miBolita miTablero -- 重复两次sacar操作
针对你现有代码的调整说明
你的现有repetir签名是(a -> b -> c) -> Int -> Tablero -> Tablero,如果要兼容单参数函数,需要注意:
- 像
obtenerIndice :: (Int,Int) -> Int这类纯单参数函数(输入输出类型不同),无法直接作为自函数重复执行。如果需要用repetir处理它,你需要将其包装为自函数(比如让输入输出类型一致,或者结合Tablero生成Tablero -> Tablero的变换函数)。 - 如果你的
repetir核心是对Tablero进行重复变换,建议优先用方案一,将双参数函数转为Tablero -> Tablero的自函数后再重复。
内容的提问来源于stack exchange,提问作者87nsilva
相关产品推荐
相关产品推荐

