这里是 Haskell 的新手。
我想写:
take 1 $ take 2 [1, 2, 3] -- = 1
Run Code Online (Sandbox Code Playgroud)
reversed,就像这个伪代码:
[1, 2, 3] -> take 2 -> take 1 -- = 1
Run Code Online (Sandbox Code Playgroud)
在 Clojure 中,我们可以这样做:
(->> [1 2 3]
(take 2)
(take 1)) ;=> (1)
Run Code Online (Sandbox Code Playgroud)
Clojure 这样做是因为它->>是一个将表达式重写为 的宏(take 1 (take 2 [1 2 3])),但是因为 Haskell 是懒惰的并且有partials 之类的,所以看起来应该很容易。
我想这样做是因为先获取数据然后读取函数以便执行它们是阅读代码的好方法。我被Clojure宠坏了!
它类似于var.action1().action2()面向对象语言中等的流畅接口/链模式。
我想这在 Template Haskell 中是可能的,但肯定有一种我还不知道的内置方法来做到这一点?谢谢!
这个功能有什么问题?这似乎是一个范围错误(虽然我认为我通过将每个callable放在列表中而不是直接使用它来修复它).错误是达到最大递归深度(调用comp(inv,dbl,inc)时)...
注意:问题是:为什么它甚至会递归,而不是它达到最大深度的原因......
def comp(*funcs):
if len(funcs) in (0,1):
raise ValueError('need at least two functions to compose')
# get most inner function
composed = []
print("appending func 1")
composed.append(funcs[-1])
# pop last and reverse
funcs = funcs[:-1][::-1]
i = 1
for func in funcs:
i += 1
print("appending func %s" % i)
composed.append(lambda *args, **kwargs: func(composed[-1](*args,**kwargs)))
return composed[-1]
def inc(x):
print("inc called with %s" % x)
return x+1
def dbl(x):
print("dbl called with %s" % x)
return x*2
def inv(x):
print("inv …Run Code Online (Sandbox Code Playgroud) python recursion functional-programming composition function-composition
所以我正在写一行来获取列表的倒数第二个元素.最初我的代码是
mySLast x = last.take ((length x) - 1) x
Run Code Online (Sandbox Code Playgroud)
哪个last功能一直有效.意识到我的take业务已经包含在Haskell中,init所以我改写为
mySLast = last.init
Run Code Online (Sandbox Code Playgroud)
这仍然不起作用.我觉得这是令人费解,因为init::[a]->[a]和last::[a]->a所以他们绝对应该在组合的同态Hask类别.
我试过问Haskell它认为类型是什么,它说
ghci> :t last.init
last.init :: [c] -> c
ghci> last.init [3,2,4,1]
<interactive>:45:6:
Couldn't match expected type ‘a -> [c]’
with actual type ‘[Integer]’
Relevant bindings include
it :: a -> c (bound at <interactive>:45:1)
Possible cause: ‘init’ is applied to too many arguments
In the second argument of ‘(.)’, namely ‘init [3, …Run Code Online (Sandbox Code Playgroud) 我尝试用类型指定组合两个函数.
foo :: Num a => a -> a
foo a = a + 2
bar :: Num a => a -> a
bar a = a * 2
fooBarCompose :: (Num a, Num b, Num c) => (a -> b) -> (c -> a) -> c -> b
fooBarCompose f g = f . g
Run Code Online (Sandbox Code Playgroud)
我的模块编译,但在运行时我调用
fooBarCompose bar foo
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
No instance for (Show (b0 -> b0))
(maybe you haven't applied enough arguments to a function?)
arising from a …Run Code Online (Sandbox Code Playgroud) 如何在下面的表达式中理解函数组合?
map . foldr (.) id :: [b -> b] -> [b] -> [b]
Run Code Online (Sandbox Code Playgroud) 不知何故,我应该能够指定这样的链,同时值通过每个函数进行管道传输。
a::create -> a::processing -> a::updating -> a:uploading
Run Code Online (Sandbox Code Playgroud)
在以下文章的上下文中,我想将这些方法链接起来,其中一个方法将结果传递给下一个方法,同时修改它。
https://dzone.com/articles/higher-order-functions
https://dzone.com/articles/function-programming-java-8
我的演示将尝试展示我想要的最终结果。它将是通过管道传递给每个方法(如 monad)的单个参数/参数,并且应该更容易在链中指定任意数量的方法。
我一直在用其他语言做这件事,所以试图了解如何在 java 中做这件事。
所有方法都将接收相同类型的参数,并且仅接收一个参数。
等级值
public class Value {
public String progress = "";
}
Run Code Online (Sandbox Code Playgroud)
类文章
public class Article {
public void create(Value value) {
value.progress += "creating ";
}
public void processing(Value value) {
value.progress += "processing ";
}
public void updating(Value value) {
value.progress += "updating ";
}
public void uploading(Value value) {
value.progress += "uploading ";
}
}
Run Code Online (Sandbox Code Playgroud)
主班
public class Main {
public …Run Code Online (Sandbox Code Playgroud) 我写了一个函数count :: Char -> String -> Int来计算a Char内部的出现次数String.代码示例:
module Main where
import Data.List
main :: IO ()
main = do
print $ count 'a' "abcaaba"
count :: Char -> String -> Int
count = length . elemIndices
Run Code Online (Sandbox Code Playgroud)
我得到的编译错误是
* Couldn't match type `Int' with `String -> Int'
Expected type: Char -> String -> Int
Actual type: Char -> Int
* Possible cause: `(.)' is applied to too many arguments
In the expression: length . elemIndices …Run Code Online (Sandbox Code Playgroud) 我想改写
foldr (\_ y = y + 1) 0
Run Code Online (Sandbox Code Playgroud)
使用flip,const以及(+1)和功能的组合物.
我到目前为止:
foldr (\x -> ((+1) . (flip const x)) 0
Run Code Online (Sandbox Code Playgroud)
但我似乎无法放弃这个lambda.有没有办法这样做?
我试图理解表达式的类型(map . map).由于类型(.)是(b -> c) -> (a -> b) -> a -> c我不明白这是如何工作与地图功能,因为map取不与功能适应两个参数(b -> c)和(a -> b).
在阅读有关函数组合的教程时,我尝试了以下内容:
let prefixFun a b = a + "" + b;;
let exclaim s = s + "!";;
let bigHello = prefixFun >> exclaim;;
Run Code Online (Sandbox Code Playgroud)
但是定义bigHello返回以下类型不匹配错误
let bigHello = prefixFun >> exclaim;;
----------------------------^^^^^^^
stdin(28,29): error FS0001: Type mismatch. Expecting a
'(string -> string) -> 'a'
but given a
'string -> string'
The type 'string -> string' does not match the type 'string'
Run Code Online (Sandbox Code Playgroud)
prefixFun返回字符串并exclaim期望字符串.你能帮我理解并解决问题吗?
谢谢.
t2 = (\x y z-> x.y.x)
GHCI告诉我这个:
t2 :: (b1 -> b2) -> (b2 -> b1) -> p -> b1 -> b2
我无法理解这种类型的签名是如何形成的.到目前为止,我已经认为r-most-x基本上是一个函数,它接受a b2并返回a b1,那么这b1是中间函数的输入y,并b2再次输出?它不应该返回新类型的值b3或什么?
请执行功能:
composeApplicative :: (Applicative f) => f (b -> c) -> f (a -> b) -> f (a -> c)
Run Code Online (Sandbox Code Playgroud)
这样:
(composeApplicative f g) <*> x == f <*> (g <*> x)
Run Code Online (Sandbox Code Playgroud)
或者,解释为什么不能这样做?