在Haskell中卷曲3个参数 [英] Currying 3 Arguments in Haskell

查看:93
本文介绍了在Haskell中卷曲3个参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在currying函数中删除Haskell中的三个参数时遇到了麻烦。



免责声明:不是课程作业,我被一个今天挣扎着的人问了这个问题,它一直在困扰我。



我们给出的自定义类型/函数是(只能记住类型)

  type MyThing 
=(Char ,字符串)
类型MyThings
= [MyThing]

funcA :: MyThings - >字符串 - >字符串
funcB :: MyThings - >字符串 - > Int - >字符串

我们开始于:

  funcB as str n = iterate(funcA as)str !! n 

并将其降低如下:

  funcB as str n = iterate(funcA as)str !! n 
funcB as str =(!!)。 (iterate(funcA as))str
funcB as =(!!)。 (iterate(funcA as))
funcB as =(!!)。 (迭代。funcA)为

然后,卡住了。我们无法弄清楚如何避免使用最后一个参数。我知道我以前在某个地方曾经见过类似的情况,并且有一个解决方案。



希望Haskell的一些天才能够指出我为什么是一个白痴......

解决方案

所有你需要的是以下三个操作符部分的法则:

 (a`op` b)=(a`op`)b =(`op` b)a = op ab 
(1)(2)( 3)

以便操作数进入操作员附近的空闲插槽。



对于(。)这意味着:(a。b)=(a。)b =(。 b)a =(。)ab 。所以,

  f(g x)y !! (3)
=((!!)。f(gx))yn
=((!!)n
=(!!)(f(gx)y) (f。g)x)yn
=((!!)。)((f。g)x)yn by(1)
=(((!!)。)。(f。 g))xyn
=(((!!)。)。f。g)xyn

您应该尽可能多地进行无点转换,以便所得到的表达式对您来说仍然是可读的 - 事实上,比原来的更清晰 。 无点工具有时会产生无法读取的结果。



完全可以在中间停下来。如果你手动完成它太难了,可能也很难阅读它。



((a。) 。b)xy =(a。)(bx)y =(a。bx)y = a(bxy)是一种常见模式,您可以快速学会识别立即。所以上面的表达式可以很容易地读回来:

$ $ $ $ $ $ $ $ $($) (gx)y !! n

考虑到(。)是关联的:(b。c)=((a。b)。c)=(a。(b。c。) ))


I'm having trouble with currying a function to remove three arguments in Haskell.

Disclaimer: Not Coursework, I was asked this question by someone struggling with this today and it's been bugging me.

The custom types/functions we were given were (can only remember types)

type MyThing
  = (Char, String)
type MyThings
  = [MyThing]

funcA :: MyThings -> String -> String
funcB :: MyThings -> String -> Int -> String

We started with:

funcB as str n = iterate (funcA as) str !! n

And reduced it down as follows:

funcB as str n = iterate (funcA as) str !! n
funcB as str = (!!) . (iterate (funcA as)) str
funcB as = (!!) . (iterate (funcA as))
funcB as = (!!) . (iterate . funcA) as

Then, stuck. We just can't figure out how to avoid using the last argument. I know I've seen a similar situation somewhere before and there was a solution.

Hoping some Haskell genius can point out why I'm being an idiot...

解决方案

All you need here is the following three "laws" of operator sections:

(a `op` b) = (a `op`) b = (`op` b) a = op a b
          (1)          (2)          (3)

so that the operand goes into the free slot near the operator.

For (.) this means that: (a . b) = (a .) b = (. b) a = (.) a b. So,

f (g x) y !! n      
= (!!) (f (g x) y) n              by (3) 
= ((!!) . f (g x)) y n
= ((!!) . (f . g) x) y n
= ((!!) .) ((f . g) x) y n        by (1)
= (((!!) .) . (f . g)) x y n
= (((!!) .) . f . g) x y n

You should only do as much pointfree transformation as you're comfortable with, so that the resulting expression is still readable for you - and in fact, clearer than the original. The "pointfree" tool can at times produce unreadable results.

It is perfectly OK to stop in the middle. If it's too hard for you to complete it manually, probably it will be hard for you to read it, too.

((a .) . b) x y = (a .) (b x) y = (a . b x) y = a (b x y) is a common pattern that you will quickly learn to recognize immediately. So the above expression can be read back fairly easily as

(!!) ((f . g) x y) n = f (g x) y !! n

considering that (.) is associative:

(a . b . c) = ((a . b) . c) = (a . (b . c))

这篇关于在Haskell中卷曲3个参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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