好吧,所以我不是Haskell程序员,但我对Haskell背后的许多想法非常感兴趣,并且我正在研究它.但是我被困在第一个方面:我似乎无法绕过Monads,这似乎是相当基础的.我知道有一百万个关于SO的问题要求解释Monads,所以我会更加具体地说明了什么在困扰我:
我读了这篇优秀的文章(Javascript中的介绍),并认为我完全了解Monads.然后我读了Monads上的维基百科条目,看到了:
多态类型(M t)→(t→M u)→(M u)的绑定操作,其中Haskell由中缀运算符表示>> =.它的第一个参数是monadic类型的值,它的第二个参数是一个函数,它从第一个参数的基础类型映射到另一个monadic类型,其结果是在其他monadic类型中.
好的,在我引用的文章中,bind是一个仅占用一个参数的函数.维基百科说两个.我认为我对Monads的理解如下:
但是肯定有一些错误,因为我的bind概念需要一个参数:一个函数.但是(根据维基百科)Haskell的绑定实际上有两个参数!我的错误在哪里?
def sub3(n):
return n - 3
def square(n):
return n * n
Run Code Online (Sandbox Code Playgroud)
在python中组合函数很容易:
>>> my_list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [square(sub3(n)) for n in my_list]
[9, 4, 1, 0, 1, 4, 9, 16, 25, 36]
Run Code Online (Sandbox Code Playgroud)
不幸的是,当想要使用合成作为关键时,它有点蹩脚:
>>> sorted(my_list, key=lambda n: square(sub3(n)))
[3, 2, 4, 1, 5, 0, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)
这真的应该是sorted(my_list, key=square*sub3),因为heck,函数__mul__不用于其他任何事情:
>>> square * sub3
TypeError: unsupported operand type(s) for *: 'function' and 'function'
Run Code Online (Sandbox Code Playgroud)
好吧,让我们来定义吧!
>>> …Run Code Online (Sandbox Code Playgroud) 我有一个函数数组,我正在尝试生成一个函数,该函数由我的数组中的元素组成.我的方法是:
def compose(list):
if len(list) == 1:
return lambda x:list[0](x)
list.reverse()
final=lambda x:x
for f in list:
final=lambda x:f(final(x))
return final
Run Code Online (Sandbox Code Playgroud)
这种方法似乎不起作用,将不胜感激.
(我正在颠倒列表,因为这是我想要函数的组合顺序)
python functional-programming composition function-composition
我很困惑.我可以这样写:
import Control.Monad
main = print $ head $ (foldr (.) id [f, g]) [3]
where f = (1:)
g = undefined
Run Code Online (Sandbox Code Playgroud)
而输出是1.这是有道理的,因为它减少到:
main = print $ head $ ((1:) . undefined . id) [3]
main = print $ head $ (1:) ((undefined . id) [3])
main = print $ head $ 1 : ((undefined . id) [3])
main = print $ 1
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用模糊相似的monadic技术,它不会起作用:
import Control.Monad
main = print $ (foldr (<=<) return [f, g]) 3
where f …Run Code Online (Sandbox Code Playgroud) 我真的希望Google更擅长搜索语法:
decades :: (RealFrac a) => a -> a -> [a] -> Array Int Int
decades a b = hist (0,9) . map decade
where decade x = floor ((x - a) * s)
s = 10 / (b - a)
Run Code Online (Sandbox Code Playgroud) 我正在尝试为我的大学学位制作一个能够完成其他功能的功能.例如,我想打电话给round_sqrt = round(sqrt)
,当我打电话给round_sqrt(5)它时,它必须显示我2而不是2.23606797749979.我在想的是这个:
def rounding(funct):
return round(funct)
Run Code Online (Sandbox Code Playgroud)
但这不起作用.
编辑:该函数应该只有一个参数.例如,函数的开头应该是
def rounding(func):
Run Code Online (Sandbox Code Playgroud)
所以在这个函数中,funct函数需要舍入.所以当我打电话给rounding(abs)(3.2)我看3.
我目前正在编写一些需要大量函数组合的C++ 11中的加密算法.我必须处理两种类型的构图:
自己编写一个函数可变次数.在数学上,对于某个函数F,F ^ n(x)=(F ^ {n-1} o F)(x)= F ^ {n-1}(F(x)).
一起组合不同的功能.例如,对于相同类型的一些函数f,g,h,i,j和k,我将具有f(g(h(i(j(k(x)))))).
就我而言,我使用的是F的以下定义:
const std::vector<uint8_t> F(const std::vector<uint8_t> &x);
Run Code Online (Sandbox Code Playgroud)
我想自己组合这个功能n次.我已经以一种简单的递归方式实现了组合,它工作正常:
const std::vector<uint8_t> compose(const uint8_t n, const std::vector<uint8_t> &x)
{
if(n > 1)
return compose(n-1, F(x));
return F(x);
}
Run Code Online (Sandbox Code Playgroud)
对于这种情况,是否有一种更有效的方法来使用c ++ 11实现此组合但不使用BOOST?如果可能的话,使用这个表格会很棒:
answer = compose<4>(F)(x); // Same as 'answer = F^4(x) = F(F(F(F(x))))'
Run Code Online (Sandbox Code Playgroud)
对于第二种情况,我想实现可变数量的函数的组合.对于给定的一组函数F0,F1,...,Fn具有与F相同的定义,是否有一种有效且合适的方法来组合它们,其中n是可变的?我认为可变参数模板在这里很有用,但在这种情况下我不知道如何使用它们.
谢谢你的帮助.
我遇到过andThen,但没有正确理解它.
为了进一步研究,我阅读了Function1.andThen 文档.
def andThen[A](g: (R) ? A): (T1) ? A
Run Code Online (Sandbox Code Playgroud)
mm是一个MultiMap实例.
scala> mm
res29: scala.collection.mutable.HashMap[Int,scala.collection.mutable.Set[String]] with scala.collection.mutable.MultiMap[Int,String] =
Map(2 -> Set(b) , 1 -> Set(c, a))
scala> mm.keys.toList.sortWith(_ < _).map(mm.andThen(_.toList))
res26: List[List[String]] = List(List(c, a), List(b))
scala> mm.keys.toList.sortWith(_ < _).map(x => mm.apply(x).toList)
res27: List[List[String]] = List(List(c, a), List(b))
Run Code Online (Sandbox Code Playgroud)
注 - 来自行动中的DSL的代码
是andThen强大的?基于这个例子,看起来像mm.andThen去糖x => mm.apply(x).如果有更深刻的含义andThen,那么我还没有理解它.
前段时间我查看了Haskell文档,发现它的功能组合运算符非常好.所以我实现了这个小装饰:
from functools import partial
class _compfunc(partial):
def __lshift__(self, y):
f = lambda *args, **kwargs: self.func(y(*args, **kwargs))
return _compfunc(f)
def __rshift__(self, y):
f = lambda *args, **kwargs: y(self.func(*args, **kwargs))
return _compfunc(f)
def composable(f):
return _compfunc(f)
@composable
def f1(x):
return x * 2
@composable
def f2(x):
return x + 3
@composable
def f3(x):
return (-1) * x
@composable
def f4(a):
return a + [0]
print (f1 >> f2 >> f3)(3) #-9
print (f4 >> f1)([1, 2]) #[1, 2, 0, 1, 2, …Run Code Online (Sandbox Code Playgroud) 我决定今天是我修复一些不必要地在monadic动作中运行的纯函数的那一天.这就是我所拥有的.
flagWorkDays :: [C.Day] -> Handler [WorkDay]
flagWorkDays dayList =
flagWeekEnds dayList >>=
flagHolidays >>=
flagScheduled >>=
flagASAP >>=
toWorkDays
Run Code Online (Sandbox Code Playgroud)
这是flagWeekEnds,截至目前.
flagWeekEnds :: [C.Day] -> Handler [(C.Day,Availability)]
flagWeekEnds dayList = do
let yepNope = Prelude.map isWorkDay dayList
availability = Prelude.map flagAvailability yepNope
return $ Prelude.zip dayList availability
Run Code Online (Sandbox Code Playgroud)
flagHolidays遵循类似的模式.toWorkDays只是将一种类型更改为另一种类型,并且是纯函数.
flagScheduled,flagASAP是monadic行动.我不确定如何将monadic动作与惯用语中的纯函数结合起来flagWorkDays.有人可以帮我解决flagWorkDays,假设flagWeekEnds并且flagHolidays已经变得纯净了吗?