如何创建多变量haskell函数? [英] How to create a polyvariadic haskell function?

查看:27
本文介绍了如何创建多变量haskell函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个函数,它接受任意数量的参数(所有相同类型),用它们做一些事情,然后返回一个结果.在我的特定情况下,参数列表是不切实际的.

I need a function which takes an arbitrary number of arguments (All of the same type), does something with them and afterwards gives a result back. A list of arguments is impracticable in my specific case.

当我查看 haskell 库时,我看到函数 printf(来自模块 Text.Printf)使用了类似的技巧.不幸的是,我无法通过查看来源来理解这种魔力.

As I looked through the haskell libs, I saw that the function printf (from module Text.Printf) uses a similar trick. Unfortunately, I couldn't understand that magic by looking at the source.

有人可以解释如何实现这一点,或者至少可以在一些网页/论文/任何我可以找到对此进行很好描述的地方吗?

Can somebody explain how to achieve this, or at least some webpage/paper/whatever where I could find a good description for this?

动机:

我需要这个的原因真的很简单.对于学校(计算机科学课),我们需要编写一个能够记录"数学表达式的模块,将其表示为字符串(通过为自己的数据类型编写 Num/Real/etc 的实例),并执行对其进行各种操作.

The reason I need this is really quite simple. For school (computer science class), we are required to write a module that is able to "record" a mathematical expression, express it as a string (Via writing an instance of Num/Real/etc for an own datatype), and perform various operations on it.

这个数据类型包含一个特殊的变量构造函数,它可以被一个值或任何指定的函数替换.目标之一是编写一个函数,该函数采用具有一定数量变量的表达式((Char,Rational) 类型的对)并计算表达式的结果.我们应该看看如何最好地表达函数的目标.(我的想法:该函数返回另一个函数,该函数采用与函数中定义的 var 完全一样多的参数 - 似乎是不可能的.

This datatype contains a special constructor for a variable, which may be replaced by a value or whatever by a specified function. One of the goals is to write a function, which takes such an expression with some number of variables (pairs of type (Char,Rational)) and calculates the result of the expression. We should look at how to express the goal of the function best. (My idea: The function returns another function which takes exactly as many arguments as vars that are defined in the function - seems to be impossible).

推荐答案

printf 的关键点是能够返回字符串或函数.复制自 http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/src/Text-Printf.html

The key points of printf is the ability to either return a String or a function. Copied from http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/src/Text-Printf.html,

printf :: (PrintfType r) => String -> r
printf fmts = spr fmts []

class PrintfType t where
    spr :: String -> [UPrintf] -> t

instance (IsChar c) => PrintfType [c] where
    spr fmts args = map fromChar (uprintf fmts (reverse args))

instance (PrintfArg a, PrintfType r) => PrintfType (a -> r) where
    spr fmts args = a -> spr fmts (toUPrintf a : args)

我们可以提取出的基本结构是

and the basic structure we can extract out is

variadicFunction :: VariadicReturnClass r => RequiredArgs -> r
variadicFunction reqArgs = variadicImpl reqArgs mempty

class VariadicReturnClass r where
   variadicImpl :: RequiredArgs -> AccumulatingType -> r

instance VariadicReturnClass ActualReturnType where
   variadicImpl reqArgs acc = constructActualResult reqArgs acc

instance (ArgClass a, VariadicReturnClass r) => VariadicReturnClass (a -> r) where
   variadicImpl reqArgs acc = a -> variadicImpl reqArgs (specialize a `mappend` acc)

例如:

class SumRes r where 
    sumOf :: Integer -> r

instance SumRes Integer where
    sumOf = id

instance (Integral a, SumRes r) => SumRes (a -> r) where
    sumOf x = sumOf . (x +) . toInteger

然后我们可以使用

*Main> sumOf 1 :: Integer
1
*Main> sumOf 1 4 7 10 :: Integer
22
*Main> sumOf 1 4 7 10 0 0  :: Integer
22
*Main> sumOf 1 4 7 10 2 5 8 22 :: Integer
59

这篇关于如何创建多变量haskell函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆