我只是想对我的Haskell代码进行一般性改进,并且想知道以下函数是否可以无点编写?主要是出于好奇心的缘故.
给出了我们想要在我们中使用的两个函数filter:
isZero = (==0)
isOne = (==1)
Run Code Online (Sandbox Code Playgroud)
我们如何在我们的设计示例中使用这两个函数,但是使其无点?
filter (\x -> isZero x || isOne x) [0..100]
Run Code Online (Sandbox Code Playgroud)
Igo*_*dov 23
有一个将代码转换为无点的在线服务Haskell.
它表明: filter (liftM2 (||) isZero isOne) [0..100]
liftA2 (||) isZero isOne或者(||) <$> isZero <*> isOne也是可能的
(||) <$> isZero有类型a0 -> Bool -> Bool,它的组成(||)和isZero.该组合采用数字(for isZero)和布尔值(作为另一个参数(||))
所以,它是一样的 \x y -> (||) (isZero x) y
函数类型是一个实例,Applicative Functor我们可以看看它的实现:
instance Applicative ((->) r) where
pure x = (\_ -> x)
f <*> g = \x -> f x (g x)
Run Code Online (Sandbox Code Playgroud)
所以,(||) <$> isZero <*> isOne是一样的,\x -> ((||) <$> isZero) x (isOne x)一样的\x -> (||) (isZero x) (isOne x)
因此,如果存在z x = y (f x) (g x),它可以转换为无点:z = y <$> f <*> g
另一种无点形式是使用a -> Any幺半群:
? import Data.Monoid (Any(..))
? :t getAny . (Any . isZero <> Any . isOne)
getAny . (Any . isZero <> Any . isOne)
:: (Num a, Eq a) => a -> Bool
? filter (getAny . (Any . isZero <> Any . isOne)) [0..100]
[0,1]
Run Code Online (Sandbox Code Playgroud)
它比Applicative解决方案长一点,但我认为当你有更多的条件要结合时,它会更容易理解.相比
getAny . (Any . isZero <> Any . isOne <> Any . isSquare <> Any . isPrime)
Run Code Online (Sandbox Code Playgroud)
要么
getAny . foldMap (Any .) [isZero, isOne, isSquare, isPrime]
Run Code Online (Sandbox Code Playgroud)
和
liftA2 (||) (liftA2 (||) (liftA2 (||) isZero isOne) isSquare) isPrime
Run Code Online (Sandbox Code Playgroud)
要么
liftA2 (||) isZero $ liftA2 (||) isOne $ liftA2 (||) isSquare isPrime
Run Code Online (Sandbox Code Playgroud)
虽然说实话,如果我有很多这样的事情,我很想定义<||> = liftA2 (||)和做
isZero <||> isOne <||> isSquare <||> isPrime
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1421 次 |
| 最近记录: |