包括我在内的许多haskell程序员都喜欢无意义的风格,特别是在编写复杂的解析器时.它们使代码更具可读性和更简洁.但有时,它只是反过来(例如在滥用实例Monad和朋友时(->) a).
请给我一些基本的指导,你什么时候认为毫无意义的风格是有用的,何时不是.例如,如果我不得不使用部分组合(类似的话flip ((.) . take) . drop),我总是使用lambda .
一个相关的问题是this,但有些答案说几乎任何东西都可以免费点,那么这个功能有什么问题呢?
\[x] -> x
Run Code Online (Sandbox Code Playgroud)
http://pointfree.io/似乎无法以无点风格编写它。这是否意味着它不能这样写?如果是这样,它的理论原因是什么?
我只能观察到上面的函数是head(或last,fwiw)的“残缺”版本,它只能在单例列表上运行。实际上,应用于非单例列表时,它会以这种方式出错ghci:
*** Exception: <interactive>:380:5-13: Non-exhaustive patterns in lambda
Run Code Online (Sandbox Code Playgroud)
也许模式上的“非穷尽性”是某些函数不能以无点风格编写的原因?
根据答案编辑:
我没想到我的问题的答案会如此复杂(我觉得我只是认为简短的答案是否定的,实际上不可能),所以我需要找一些时间仔细阅读它们,尝试一下,然后全神贯注于它们,否则我无法决定应该接受哪一个。目前,对 Jon Purdy 的回答 +1,我可以很容易地理解这是我将在普通代码中停下的地方。
我一直在玩Haskell,包括练习以无点形式编写函数.这是一个示例函数:
dotProduct :: (Num a) => [a] -> [a] -> a
dotProduct xs ys = sum (zipWith (*) xs ys)
Run Code Online (Sandbox Code Playgroud)
我想以无点形式编写这个函数.这是我在其他地方找到的一个例子:
dotProduct = (sum .) . zipWith (*)
Run Code Online (Sandbox Code Playgroud)
但是,我不明白为什么无点形式看起来像(sum .) . zipWith (*)而不是sum . zipWith (*).为什么括号中的和有2个组合运算符?
我正在尝试编写一个可变函数组合函数.基本上(.)除了第二个参数函数是可变参数之外.这应该允许表达式:
map even . zipWith (+)
Run Code Online (Sandbox Code Playgroud)
要不就
map even . zipWith
Run Code Online (Sandbox Code Playgroud)
目前,如果我添加IncoherentInstances并且需要第一个参数函数的非多态实例,我已达到的工作.
{-# LANGUAGE FlexibleInstances, OverlappingInstances, MultiParamTypeClasses,
FunctionalDependencies, UndecidableInstances, KindSignatures #-}
class Comp a b c d | c -> d where
comp :: (a -> b) -> c -> d
instance Comp a b (a :: *) (b :: *) where
comp f g = f g
instance Comp c d b e => Comp c d (a -> b) (a -> e) where
comp …Run Code Online (Sandbox Code Playgroud) 假设我有一个mean如此定义的函数:
mean xs = sum xs / (fromIntegral $ length xs)
Run Code Online (Sandbox Code Playgroud)
但我想以某种默契形式,像这样:
mean = sum / (fromIntegral . length)
Run Code Online (Sandbox Code Playgroud)
是否有内置的Haskell方法可以在这些行中执行某些操作而无需构建自己的tacit函数(类似这样):
tacit :: (a -> b -> c) -> (d -> a) -> (d -> b) -> d -> c
tacit a b c i = a (b i) (c i)
Run Code Online (Sandbox Code Playgroud)
在这种形式中,函数如下所示:
mean = tacit (/) sum (fromIntegral . length)
Run Code Online (Sandbox Code Playgroud)
但感觉可能有一种方法可以避免使用像这样的显式函数.我是在想; 是否有一些方法可以做到内置于Haskell?
我想知道是否可以使用带有多个参数的函数进行功能组合.我希望能够做这样的事情
x = (+3).(*)
Run Code Online (Sandbox Code Playgroud)
设置x等于将两个数字的乘积加三的函数.
我在Haskell有一个任务(不,这不是我的功课,我正在学习考试).
任务是:
写入无点函数
numocc,用于计算给定列表中元素的出现次数.例如:numocc 1 [[1, 2], [2, 3, 2, 1, 1], [3]]=[1, 2, 0]
这是我的代码:
addif :: Eq a => a -> Int -> a -> Int
addif x acc y = if x == y then acc+1 else acc
count :: Eq a => a -> [a] -> Int
count = flip foldl 0 . addif
numocc :: Eq a => a -> [[a]] -> [Int]
numocc = map . count
Run Code Online (Sandbox Code Playgroud)
numocc并且count …
这是我在某处遇到的代码,但想知道它是如何工作的:
findIndices :: (a -> Bool) -> [a] -> [Int]
findIndices _ [] = []
findIndices pred xs = map fst (filter (pred . snd) (zip [0..] xs))
Run Code Online (Sandbox Code Playgroud)
输出:findIndices (== 0) [1,2,0,3,0]==[2,4],其中pred是(==0)&xs是[1,2,0,3,0]
我将展示我的一些理解:
(zip [0..] xs)
Run Code Online (Sandbox Code Playgroud)
上面一行的作用是为列表中的所有内容添加索引。对于上面给出的输入,它是这样的:[(0,1),(1,2),(2,0),(3,3),(4,0)]。
(pred . snd)
Run Code Online (Sandbox Code Playgroud)
我发现这意味着类似于pred (snd (x)). 我的问题是,x列表是由该zip行制作的吗?我倾向于是,但我的猜测是站不住脚的。
接下来是我对fstand 的理解snd。我知道
fst(1,2) = 1
Run Code Online (Sandbox Code Playgroud)
和
snd(1,2) = 2
Run Code Online (Sandbox Code Playgroud)
这两个命令如何在代码中有意义?
我的理解filter是它返回匹配条件的项目列表。例如, …
haskell composition pointfree function-composition higher-order-functions
我试图了解如何在Haskell中将函数转换为无点表示法.我看到了这个例子,但它比我想要的更复杂.我觉得我理解它背后的逻辑,但当我试图在代码中执行一些简单的例子时,我得到了编译错误.我想尝试以无点样式编写此函数:
f x = 5 + 8/x 我重新安排为 f x = (+) 5 $ (/) 8 x
所以,我认为它可能是这样的:
f = (+) 5 $ (/) 8
Run Code Online (Sandbox Code Playgroud)
但是当我在ghci中运行时,我得到这样的信息:
No instance for (Num (a0 -> a0))
arising from the literal `5' at Test.hs:3:9
Possible fix: add an instance declaration for (Num (a0 -> a0))
In the first argument of `(+)', namely `5'
In the first argument of `($)', namely `(+) 5'
In the expression: (+) 5 $ (/) 8
Failed, modules …Run Code Online (Sandbox Code Playgroud) 我想知道如何f x = zip x (tail x)免费写点.所以我使用了pointfree程序,结果是f = ap zip tail.ap是Control.Monad的一个函数
我不明白点自由定义是如何工作的.如果我能从类型的角度理解它,我希望我能弄明白.
import Control.Monad (ap)
let f = ap zip tail
let g = ap zip
:info ap zip tail f g
ap :: Monad m => m (a -> b) -> m a -> m b
-- Defined in `Control.Monad'
zip :: [a] -> [b] -> [(a, b)] -- Defined in `GHC.List'
tail :: [a] -> [a] -- Defined in `GHC.List'
f :: …Run Code Online (Sandbox Code Playgroud)