![](/img/trans.png)
[英]Using functors/applicatives on custom data types with multiple type classes?
[英]Haskell type magical world of Oz filtering nicta course functors and applicatives
取自NICTA课程 :
-- | Filter a list with a predicate that produces an effect.
--
-- >>> filtering (Id . even) (4 :. 5 :. 6 :. Nil)
-- Id [4,6]
--
-- >>> filtering (\a -> if a > 13 then Empty else Full (a <= 7)) (4 :. 5 :. 6 :. Nil)
-- Full [4,5,6]
--
-- >>> filtering (\a -> if a > 13 then Empty else Full (a <= 7)) (4 :. 5 :. 6 :. 7 :. 8 :. 9 :. Nil)
-- Full [4,5,6,7]
--
-- >>> filtering (\a -> if a > 13 then Empty else Full (a <= 7)) (4 :. 5 :. 6 :. 13 :. 14 :. Nil)
-- Empty
--
-- >>> filtering (>) (4 :. 5 :. 6 :. 7 :. 8 :. 9 :. 10 :. 11 :. 12 :. Nil) 8
-- [9,10,11,12]
--
-- >>> filtering (const $ True :. True :. Nil) (1 :. 2 :. 3 :. Nil)
-- [[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
--
filtering :: Applicative f => (a -> f Bool) -> List a -> f (List a)
我不了解此功能的签名。
“它需要一个函数(a -> f Bool)
和一个List a
并返回一个f (List a)
”
第一个例子:
-- >>> filtering (Id . even) (4 :. 5 :. 6 :. Nil)
-- :type (. even)
-- (Bool -> c) -> a -> c
给定: data Id a = Id a
这是怎么发生的:
-- :type (Id . even)
-- a -> Id Bool
我明白这一点:
-- >>> filtering (\a -> if a > 13 then Empty else Full (a <= 7)) (4 :. 5 :. Nil)
那两个呢?
-- >>> filtering (>) (4 :. 5 :. Nil) 8
-- >>> filtering (const $ True :. True :. Nil) (1 :. 2 :. Nil)
-- :type Id
-- a -> Id a
-- :type filtering
-- (a -> f Bool) -> List a -> f (List a)
-- :type filtering Id
-- List Bool -> Id (List Bool)
-- Functor f is Id
-- (a -> f Bool) is replaced by (Bool -> Id Bool)
同理:
-- :type (<)
-- a -> a -> Bool
-- :type filtering
-- (a -> f Bool) -> List a -> f (List a)
-- :type filtering (<)
-- List a -> a -> List a
-- Functor f is (-> a)
-- (a -> f Bool) is replaced by (a -> a -> Bool)
我这样想
其他问题:
-- :type Id
-- a -> Id a
-- :type (. even)
-- (Bool -> c) -> a -> c
-- :type (Id . even)
-- a -> Id Bool
我不明白最终的转变。
通过aweinstock给出答案:
(Id :: a -> Id a)
放在(Bool -> c)
((. even) :: (Bool -> c) -> a -> c)
,因此“ a”与“ Bool”,因此“ c”与“ Id Bool”统一
首先,考虑一下您现有的Applicative
实例:
instance Applicative Id where instance Applicative List where instance Applicative Optional where instance Applicative ((->) t) where
现在, filtering
具有以下类型
filtering :: Applicative f => (a -> f Bool) -> List a -> f (List a)
我们专注于filtering (>)
。 (>)
类型为Ord a => a -> a -> Bool
。 这立即修复了Applicative
的实例:它是((->) t)
:
filtering (>) :: Ord a => List a -> ((-> a) List a)
-- or, written in the usual `a ->` style:
filtering (>) :: Ord a => List a -> (a -> List a)
因此, filtering (>)
接受List a
并返回一个期望单个值的函数,最终返回一个list:
filtering :: Applicative f => (a -> f Bool) -> List a -> f (List a)
filtering (>) :: Ord a => List a -> (a -> List a)
filtering (>) (4 :. 5 :. Nil) :: Int -> List Int
filtering (>) (4 :. 5 :. Nil) 8 :: List Int
顺便说一句,如果您使用GHCi并提供filtering
类型但没有(有效)实现,则可以轻松检查类型:
ghci> let filtering :: Applicative f => (a -> f Bool) -> [a] -> f [a]; filtering = undefined
ghci> :t filtering (>)
filtering (>) :: Ord a => [a] -> a -> [a]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.