English 中文(简体)
通过清单要素作为治疗功能的参数
原标题:Passing list elements as parameters to curried function

这里还有Haskell新bie。 我知道,仅仅够了,才有错的假设。 如果我有以下职能......

quadsum w x y z = w+x+y+z

我希望能包含一个清单的功能,在<代码>quadsum<>/code>等特定职能中使用每个要素作为参数,并将一个治愈功能退回,供日后使用。

我一直在试图使......发挥作用。

magicalFunctionMaker f [] = (f)
magicalFunctionMaker f (x:xs) = magicalFunctionMaker (f x) xs

希望能够这样做......

magicalFunctionMaker (quadsum) [4,3,2]

发挥治疗作用,例如:

(((quadsum 4) 3) 2)

或者,呼吁:

magicalFunctionMaker (quadsum) [4,3,2,1]

......

((((quadsum 4) 3) 2) 1)

这是可能的吗? 我是如何误导的?

最佳回答

保罗·约翰逊的答案相当高。 正义

quadsum 4 3 2

其结果将是你想要的职能,编号为。 Integer -> Integer

但是,有时这还不够。 有时,你拿到人数清单,你不知道名单是多少,你需要把这些内容运用到你的职能中。 这比以往更加困难。 你可以做:

magicalFunction2 f [] = f
magicalFunction2 f (x1:x2:xs) = f x1 x2

由于结果不同。 在第一种情况下,结果需要两个论点,其次,它具有完全适用的职能,因此不再允许提出论据。 在本案中,最好的事情是列入清单和您的原始职能,直到有足够的论据:

type PAPFunc f a result = Either (f, [a]) result

magicfunc f xs = Left (f,xs)

apply (Left (f,xs)) ys = Left (f,xs++ys)
apply p _              = p

simp2 :: PAPFunc (a->a->b) a b -> PAPFunc (a->a->b) a b
simp2 (Left (f,(x1:x2:xs))) = Right (f x1 x2)
simp2 p = p

现在你可以做:

Main> let j = magicfunc (+) []
Main> let m = apply j [1]
Main> let n = apply m [2,3]

Main> either (const "unfinished") show $ simp2 m
"unfinished"
Main> either (const "unfinished") show $ simp2 n
"3"

每一ar都需要单独的简化功能,而这个问题最容易由Tmlate Haskell确定。

使用论点清单(而不是清单论点)往往在Haskell非常宽松,因为多重结果都有不同类型,对不同类型论点的收集的支持很少。 我看到三种解决办法:

  1. Explicitly code for each case separately (quickly becomes a lot of work).

  2. Template Haskell。

  3. 类型系统 ha。

我的回答大多涉及试图使1个不那么痛苦。 2 和3 不是心脏。

Edit:它指出,有,有 href=http://hackage.haskell.org/ Package/iteratee” rel=“nofollow noreferer”>。 使用“特定”:

import qualified Data.Iteratee as It
import Control.Applicative

magic4 f = f <$> It.head <*> It.head <*> It.head <*> It.head

liftedQuadsum = magic4 quadsum
-- liftedQuadsum is an iteratee, which is essentially an accumulating function
-- for a list of data

Main> p <- It.enumChunk (It.Chunk [1]) liftedQuadsum
Main> It.run p
*** Exception: EofException
Main> q <- It.enumChunk (It.Chunk [2,3,4]) p
Main> It.run q
10

但是,“指标”和“计算器”可能超高技能。

问题回答

我认为你误解了Haskell型系统。

首先,你的“消费”功能已经治愈。 您可以撰写“第四卷3”,并重新发挥预期二和一为额外论点的职能。 当你写“等于”((((第4款))3 21)”时。

在Haskell, ger类与ger类或图象((4,3,2,1)不同。 有鉴于此,很难理解你试图做些什么。 如果你写这句话,应该怎么办?

magicalFunctionMaker quadsum [5,4,3,2,1]

你们的“职能”只看着“双重”的意思,但你赋予的职能只能有两点理由。 因此,你可以写:

mySum = foldl (+) 0

这一职能包含一份清单,并汇总各项内容。

(WBTW, 一旦你 gr,就了解双倍和双倍之间的差异。)

Edit:

在重新讨论你的问题之后,我认为你正在设法:

magicalFunctionMaker quadSum [4,3,2,1] :: Integer
magicalFunctionMaker quadSum [4,3,2] :: Integer -> Integer

这样做是不可能的,因为神职员工的类型取决于名单理由的长短,这意味着动态打字。 正如有人说的,聚氯乙烯功能可以做一些事情(尽管没有清单理由),但这需要一小 few。

我也谈到这个问题: 我有这样的职能。

someFunc :: Int -> Int -> Int -> Int

我所爱的是发挥神职的作用,例如,

listApply :: [Int] -> (Int -> Int -> Int -> Int) -> Int

我可以这样说:

listApply [1,2,3] someFunc

诚然,约翰的答复似乎同意,应当能够做某些类型的制度,以便做到这一点。 解决类似问题的办法包括:明确采用直截复式数据型,并安装清晰的滚动和滚动(例如,见类型和方案编制语言第20章,或

我对一个时期的类型解决办法表示赞扬;它感到可能,但我很想在决定暂停Haskell号试验之前就这样做,还有许多朋友。

{-# LANGUAGE TemplateHaskell #-}    

import Language.Haskell.TH
import Language.Haskell.TH.Syntax

lApply :: [Int] -> String -> ExpQ
lApply    []  fn = return $ VarE (mkName fn)
lApply (l:ls) fn = [| $(lApply ls fn) l |]

(使用局域网(LANGUAGE pragma)或-XTemplateHaskell指挥线开关)

为此,请你在像这样多的ice子里发出呼吁:

> $(lApply [1,2] "+")
3

请注意,我必须使用载有我要求的职能名称的说明: 我可以把一项职能直接提升为“ExpQ”,但我可以提及它具有全球约束力。 我可以看看看这怎么会消失。 此外,由于我们歪曲清单的方式,必须在名单上提出相反的论点。

还有其他几个小块:为了将这种数据普及到其他数据类别,这些类型必须在提升类别中相应地出现。 例如,双双亲没有作用,但你可以轻易做到:

instance Lift Double where
        lift x = return $ LitE (RationalL (toRational x))

Lit数据型没有双立构体,但FendnalL可在其位置上使用,因为它向Fractional阶级的一名普通成员ice。

如果你想要利用这种职能,把各种类型的职能作为论据,那么你就未能通过名单,因为名单不能有好有坏。 你们可以使用les子来做这项工作,而使用Tmlate Haskell则实在在在地不难。 在这种情况下,你发挥一种功能,产生一种功能,即掌握内部适当类型的教学,并按你所希望的职能绘制地图。 或者,你可以在精心设计的ADT中总结你的论点类型,这附带了你也可以用Template Haskell制造。 这留待读者:

最后,所有标准模板都适用。 例如,由于对GHC的阶段限制,你可以将这一职能从该模块中划出。

模板Haskell是无味和令人感兴趣的 st脚,但为了完全诚实地对待无源数据类型的解决办法,或许是一种比较高的业绩,显然不需要额外使用TH。 如果我得到以下工作的话,我就会回头并采取后续行动:

不适用。 Integer。

我将赞扬我的另一个职位,但这一职位对于我自己来说足够大。

在这里,用一种“神灵”做这种事,但我觉得自己喜欢做些什么,因为它需要一种特定的取消功能(下文更是)。

首先,要界定一种重复数据类型

data RecT a = RecR a
            | RecC (a -> RecT a)

因此,类型回收的变量要么只是一种总结结果(RecR),要么是持续入侵(RecC)。

现在,我们怎样做些什么,把它归入甲型六氯环己烷?

价值很容易:

valRecT x = RecR x

RecR x显然是甲型六氯环己烷。

什么职能需要一个论点,如id?

idRecT x = RecC $ x -> RecR x

回收中心总结一种功能,即有变数和回归类型。 表达

x -> RecR x

只是这种职能,因为正如我们在RecR x之前所观察到的那样,是甲型六氯环己烷。

更一般而言,任何单一担保功能都可以取消:

lift1RecT :: (a -> a) -> RecT a
lift1RecT fn = RecC $ a -> RecR $ fn a

我们可以通过反复总结雷杰内部更深层次的职能来概括:

lift2RecT :: (a -> a -> a) -> RecT a
lift2RecT fn = RecC $  -> RecC $ a -> RecR $ fn b a

lift3RecT :: (a -> a -> a -> a) -> RecT a
lift3RecT fn = RecC $ c -> RecC $  -> RecC $ a -> RecR $ fn c b a

因此,我们尽了一切努力,将一系列武断理由的职能变成一种单一类型,RecT a。 我们如何利用这一点?

我们可以轻松地勾划一个职能应用等级:

reduceRecT :: RecT a -> a -> RecT a
reduceRecT (RecC fn) = fn
reduceRecT  _        = undefined

换言之,减少退税的理由是甲型六氯环己烷和乙型乙型乙型乙型乙型乙型乙型乙型乙型乙型乙型乙型乙型六氯环己烷,而后一种新丙型六氯环己烷则降为一级。

我们还可以在回收局内进行成品计算:

unrollRecT :: RecT a -> a
unrollRecT (RecR fn) = fn
unrollRecT  _        = undefined

我们现在重新准备把论点清单应用于一项职能!

lApply :: [a] -> RecT a -> a
lApply    []  fn = unrollRecT fn
lApply (l:ls) fn = lApply ls $ (reduceRecT fn) l

让我们首先考虑基点:如果我们用计算方法重新完成计算,我们只是不理会结果,回去。 在休养案件中,我们把论据清单减少一个,然后将 f改,把名单上的头盔应用到减少的脂肪中,导致新的累犯。

让我们努力:

lApply [2,5] $ lift2RecT (**)
> 32.0

因此,这种做法的利弊? 当然,“黑星号”版本可以采用部分清单;这里提出的“完整”型解决办法就是如此(尽管我们原则上可以用某些条条条条线确定)。 这种解决办法还不利于制定与其相关的远大体更细微的编码:我们需要为所有想要使用的国家制定国家清单。 最后,如果我们想支持混合变量类型的功能,那么将这种方式概括到类似的图式解决方案中,将是非常不容易的。

当然,另一个令人感兴趣的可能性是,通过利用Tmlate Haskell生成国家清单功能来提高准确性;这消除了某些碎块,但从某种意义上来说,可以购买两种执行方案的不利条件。





相关问题
Euler Problem in Haskell -- Can Someone Spot My Error

I m trying my hand at Euler Problem 4 in Haskell. It asks for that largest palindrome formed by multiplying two three-digit numbers. The problem was simple enough, and I thought my Haskell-fu was up ...

How does foldr work?

Can anybody explain how does foldr work? Take these examples: Prelude> foldr (-) 54 [10, 11] 53 Prelude> foldr (x y -> (x+y)/2) 54 [12, 4, 10, 6] 12.0 I am confused about these executions....

Efficient queue in Haskell

How can I efficiently implement a list data structure where I can have 2 views to the head and end of the list, that always point to a head a tail of a list without expensive calls to reverse. i.e: ...

Problem detecting cyclic numbers in Haskell

I am doing problem 61 at project Euler and came up with the following code (to test the case they give): p3 n = n*(n+1) `div` 2 p4 n = n*n p5 n = n*(3*n -1) `div` 2 p6 n = n*(2*n -1) p7 n = n*(5*n -3)...

Ways to get the middle of a list in Haskell?

I ve just started learning about Functional Programming, using Haskel. I m slowly getting through Erik Meijer s lectures on Channel 9 (I ve watched the first 4 so far) and in the 4th video Erik ...

haskell grouping problem

group :: Ord a => [(a, [b])] -> [(a, [b])] I want to look up all pairs that have the same fst, and merge them, by appending all the list of bs together where they have the same a and discarding ...

Closest equivalent to subprocess.communicate in Haskell

I want to do a popen() / python s subprocess.communicate from Haskell - start a program, give it stdin, and get its stdout/stderr. What s the most direct / Haskellish way to do this?

热门标签