Applicative is a special form of functor, in our previoius post we have already discussed the functor with ((->) r);
now, we will see the beefed up functor, which is in the Applicator typeclass,and you will import the Control.Applicative module.
and we will first examine how we can apply partially applied function to the Appilcative functors. so first let's see the use example of the functor as such
ghci> :t fmap (++) (Just "hey")
fmap (++) (Just "hey") :: Maybe ([Char] -> [Char])
ghci> :t fmap compare (Just 'a')
fmap compare (Just 'a') :: Maybe (Char -> Ordering)
ghci> :t fmap compare "A LIST OF CHARS"
fmap compare "A LIST OF CHARS" :: [Char -> Ordering]
ghci> :t fmap (\x y z -> x + y / z) [3,4,5,6]
fmap (\x y z -> x + y / z) [3,4,5,6] :: (Fractional a) => [a -> a -> a]
so, what if we apply the functor mapping on the "multi-parameter" functions over functors?? first let 's see the example as below;.
ghci> let a = fmap (*) [1,2,3,4]
ghci> :t a
a :: [Integer -> Integer]
ghci> fmap (\f -> f 9) a
[9,18,27,36]
as we can see, when map (*) on the [1,2,3,4] (you can treat the [1,2,3,4] as the [] functor on the nmbers of 1,2,3,4 respectively); then you will get back a list of functors, and then you apply the function \f ->f to each of them.
this is how the Applicative typeclass is defined, it is defined in the Control.Applicative module.
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
to be an Applicative, you first has to be a Functor,and this has been manifested by the type constraint. the pure function servers as the "applicative functor instance" it means take value of any type and return an applicative functor with that value in it.
the interesting part of the Applicative functor is the <*> function. the type of the functor is f (a -> b) -> f a -> f b ;it reminds us that it resembles that of (a -> b) -> f a -> f b, which is the type of fmap function. so it means it can take a function and a funcotr and apply the function inside the functor... It basically performs a "do and run"...
so, if we were to implement the Applicative functor on Maybe type. here it is.
instance Applicative Maybe where
pure = Just
Nothing <*> _ = Nothing
(Just f) <*> something = fmap f something
the reasoning of the Just is ignored. Let's see how we can apply that Just to the Maybe type.
ghci> Just (+3) <*> Just 9
Just 12
ghci> pure (+3) <*> Just 10
Just 13
ghci> pure (+3) <*> Just 9
Just 12
ghci> Just (++"hahah") <*> Nothing
Nothing
ghci> Nothing <*> Just "woot"
Nothing
With normal functors, you can just map a function over a functor and then you can't get the result out in any general way, even if the result is a partially applied function. Applicative functors, on the other hand, allow you to operate on several functors with a single function. Check out this piece of code:
ghci> pure (+) <*> Just 3 <*> Just 5
Just 8
ghci> pure (+) <*> Just 3 <*> Nothing
Nothing
ghci> pure (+) <*> Nothing <*> Just 5
Nothing
So, you have observed, the Applicative function gives that ability to chain something together. so as in "ability to operte on several functors with a single function.", <*> is left associative.
This can be even handy and apparent if we use the <$> notation, which has the folowing signatjure.
(<$>) :: (Functor f) => (a -> b) -> f a -> f b
f <$> x = fmap f x
it just takes the (fmap) function as the infix operator,it does a lifting, so that instead of writing pure f <*> x <*> y <*> you can write fmap f x <*> y <*> ...and which can be even simplified as f <$> x <*> y <*> ...
here is the some examples that leveerage the <$> notation and other to performs some transformation.
ghci> (++) <$> Just "johntra" <*> Just "volta"
Just "johntravolta"
so, in a nutshell, the applicative function will take a applicative and returns an applicative. Hoiw cool is that..
Some times,you nee dto instruct to the just function to let it know the types. see below.
ghci> pure "Hey" :: [String]
["Hey"]
ghci> pure "Hey" :: Maybe String
Just "Hey"
Let's take another look of the <*> on list ony. it should have a type of (<*>) :: [a -> b] -> [a] -> [b]. , and it is implemented as List comporehension. and what we will get is a list comprehension behavior, where every possible function from the left list to every possible value of the right list, the resulting list has every possible combination of applying a function from left list to a value in the right one.
ghci> [(*0),(+100),(^2)] <*> [1,2,3]
[0,0,0,101,102,103,1,4,9]
and yet another like this:
ghci> [(+),(*)] <*> [1,2] <*> [3,4]
[4,5,5,6,3,4,6,8]
we will compare that of a list comprehension to that of applicative ways .
so, instead of
ghci> [ x*y | x <- [2,5,10], y <- [8,10,11]]
[16,20,22,40,50,55,80,100,110]
we can do this:
ghci> (*) <$> [2,5,10] <*> [8,10,11]
[16,20,22,40,50,55,80,100,110]
and you can easily chain operation to the Applicative functors, such as
ghci> filter (>50) $ (*) <$> [2,5,10] <*> [8,10,11]
[55,80,100,110]
IO can be made a instance of the Applicative functor, let's see how it is implemented.
instance Applicative IO where
pure = return
a <*> b = do
f <- a
x <- b
return (f x)
f <*> were specialized for IO it would have a type of(<*>) :: IO (a -> b) -> IO a -> IO b. It would take an I/O action that yields a function as its result and another I/O action and create a new I/O action from those two that, when performed, first performs the first one to get the function and then performs the second one to get the value and then it would yield that function applied to the value as its result. We used do syntax to implement it here. Remember, do syntax is about taking several I/O actions and gluing them into one, which is exactly what we do here.
However, in terms of the IO type, it is has more notion to come, for one is so called notion of sequence, becasue we are taking two I/O actions and we're sequencing, or gluing, them into one. We have to extract the function from the first I/O action, but to extract a result from an I/O action, it has to be performed.
suppose we are writing a function like below.
myAction :: IO String
myAction = do
a <- getLine
b <- getLine
return $ a ++ b
another way is writing as follow.
myAction :: IO String
myAction = (++) <$> getLine <*> getLine
if we regress to the box analogy, we can image getLine as a box that will go out into the real world and fetch us a string. Doing (++) <$> getLine <*> getLine makes a new, bigger box that sends those two boxes out to fetch lines from the terminal and then presents the concatenation of those two lines as its result.
another instance of Applicate is the (->) , do you still remember?
the real Applicative implementation for the
instance Applicative ((->) r) where
pure x = (\_ -> x)
f <*> g = \x -> f x (g x)
let's see some exapmle of Appicate on the -> r
ghci> (pure 3) "blah"
3
this makes it even more hard to understand
ghci> pure 3 "blah"
3
a more real and obscure example is like this
ghci> :t (+) <$> (+3) <*> (*100)
(+) <$> (+3) <*> (*100) :: (Num a) => a -> a
ghci> (+) <$> (+3) <*> (*100) $ 5
508
If you want to have some one-2-one association from the functor and the argument that it shall applies to (some of the zipWith functions, you can try this)
instance Applicative ZipList where
pure x = ZipList (repeat x)
ZipList fs <*> ZipList xs = ZipList (zipWith (\f x -> f x) fs xs)
and you can use the getZipList to get a Show instance of ZipList, here is some of hte ZipList function in dry run.
ghci> getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [100,100,100]
[101,102,103]
ghci> getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [100,100..]
[101,102,103]
ghci> getZipList $ max <$> ZipList [1,2,3,4,5,3] <*> ZipList [5,3,1,2]
[5,3,3,4]
ghci> getZipList $ (,,) <$> ZipList "dog" <*> ZipList "cat" <*> ZipList "rat"
[('d','c','r'),('o','a','a'),('g','t','t')]
there is also an liftA2 function defined in the Control.Applicative module. the type of the liftA2 is liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
what it does is to lift a functio which takes two parameter (like most binary operator does) . so, it takes a normal binary function and promotes it to a function that operates on two functors.
e.g of the use of liftA2 functor.
ghci> liftA2 (:) (Just 3) (Just [4])
Just [3,4]
ghci> (:) <$> Just 3 <*> Just [4]
Just [3,4]
and to generalize something from the above, we can define some function is called sequenceA, and the definition is like this:
-- file
-- applicative_sequence.hs
-- description:
-- implement a sequence applicative
import Control.Applicative
sequenceA :: (Applicative f) => [f a] -> f [a]
sequenceA [] = pure []
sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
-- no surprise, this is a recursive implementation of sequenceA
-- another way to implement this to use the foldr mehod
sequenceA' :: (Applicative f) => [f a] -> f[a]
sequenceA' [] = pure []
sequenceA' = foldr (liftA2 (:)) (pure [])
we can have some unexpected combination with the sequenceA impl, here are some
ghci> map (\f -> f 7) [(>4),(<10),odd]
[True,True,True]
ghci> and $ map (\f -> f 7) [(>4),(<10),odd]
True
-- replaced with the sequenceA methods
ghci> sequenceA [(>4),(<10),odd] 7
[True,True,True]
ghci> and $ sequenceA [(>4),(<10),odd] 7
True
with sequenceA to simulate the method call of the list comprehension .
ghci> sequenceA [[1,2,3],[4,5,6]]
[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]
ghci> [[x,y] | x <- [1,2,3], y <- [4,5,6]]
[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]
and sequenceA on the IO actions
ghci> sequenceA [getLine, getLine, getLine]
heyh
ho
woo
["heyh","ho","woo"]
分享到:
相关推荐
基于transUnet和swinUnet的医学图像分割项目实验对比,包含完整代码,可以一键运行。评估指标包括dice、iou、recall、precision等
,stm32f030无感foc方案,资料包括原理图,pcb,源程序,观测器参数,电流环参数计算表格。
分布式电源DG选址定容优化及帕累托最优解集的粒子群算法研究,多目标粒子群算法 分布式电源 DG 定容选址 网损 成本 电压偏差 通过分布式能源的选址定容确定得到帕累托最优解集,然后选择最优值进行分析,程序采用改进粒子群算法, ,核心关键词:多目标粒子群算法; 分布式电源选址定容; 网损; 成本; 电压偏差; 帕累托最优解集。,改进粒子群算法在分布式电源选址定容中的应用:优化网损与成本,考虑电压偏差
交变磁场感应材料对沥青路面温度影响的研究,交变磁场下含感应材料沥青路面温度 ,交变磁场; 感应材料; 沥青路面; 温度; 变化; 加热效率,交变磁场对含感应材料沥青路面温度的影响研究
基于Comsol模拟的三层顶板随机裂隙浆液扩散模型:考虑重力影响的瞬态扩散规律分析,Comsol模拟,考虑三层顶板包含随机裂隙的浆液扩散模型,考虑浆液重力的影响,模型采用的DFN插件建立随机裂隙,采用达西定律模块中的储水模型为控制方程,分析不同注浆压力条件下的浆液扩散规律,建立瞬态模型 ,Comsol模拟; 随机裂隙浆液扩散模型; 浆液重力影响; DFN插件; 达西定律模块储水模型; 注浆压力条件; 浆液扩散规律; 瞬态模型,Comsol浆液扩散模型:随机裂隙下考虑重力的瞬态扩散分析
对于Sqlserver数据库只是提供了简单的图形化的导出导入工具,在实际的开发和生产环境不太可能让用户在图形化的界面选择移行的对象,进行移行。 我们在数据库的移行中也遇到这种问题,需要提供一个工具给客户使用。所以我们开发了针对SQLServer数据库的cmd形式导入导出的工具。在长期的实践中不断完善,基本可以实现Oracle的导入导出工具的80%的功能,也比较的稳定。有需要的可以下载使用,也可以提供定制化的服务
内容概要:本文介绍了DeepSeek模型在不同平台上部署的方法。首先阐述了基于Ollama的本地部署,包括Ollama的安装、模型拉取以及交互模式的使用。接着讲解了DeepSeek在移动设备(iOS和Android)上的部署细节:iPhone需要通过Safari安装快捷指令,配置API Key并通过快捷指令测试运行;Android则借助Termux安装必要组件,并手动搭建Ollama环境以加载和测试模型。最后详细叙述了基于Open WebUI部署的方式,涉及Ollama、Docker Desktop及Open WebUI的安装流程及其之间的配合使用来最终达成模型的成功部署。 适用人群:面向有兴趣了解或者实际操作DeepSeek模型跨平台部署的技术开发者、研究人员以及AI爱好者。 使用场景及目标:适用于希望利用DeepSeek模型快速构建本地化应用程序、开展实验研究的用户;具体目标为掌握DeepSeek模型在桌面系统(如Linux、macOS、Windows)、iOS和Android智能手机以及云端WebUI界面上的不同部署手段和技术。 其他说明:对于每种类型的部署都提供了详细的步骤指导,旨在帮助使用者顺利完成所需工具和环境的安装,并确保模型能够正常工作。文中给出的具体链接和命令行脚本,有助于降低初次接触者的上手难度,提升部署效率和成功率。此外,还强调了一些重要的配置注意事项,例如正确输入API key以及对Ollama的初始化检查等。
,FOC 无感 混合磁链观测器 电机控制 代码 PMSM MiniDD(直驱)电机变频无感程序,包含偏心,重量,共振等感知算法,所有算法都不基于库函数,MCU底层配置完全手写
nodejs010-nodejs-cmd-shim-1.1.0-4.1.el6.centos.alt.noarch.rpm
基于S7-200 PLC的交通灯倒计时控制及组态王界面实现原理图解析,S7-200 PLC和组态王交通灯带倒计时控制 923 47 带解释的梯形图接线图原理图图纸,io分配,组态画面 ,S7-200 PLC; 交通灯; 倒计时控制; 组态王; 梯形图接线图; IO分配; 组态画面,"S7-200 PLC与组态王交通灯倒计时控制:梯形图原理及IO分配详解"
西门子四轴卧加后处理系统:828D至840D兼容,四轴联动高效加工解决方案,支持图档处理及试看程序。,西门子四轴卧加后处理,支持828D~840D系统,支持四轴联动,可制制,看清楚联系,可提供图档处理试看程序 ,核心关键词:西门子四轴卧加后处理; 828D~840D系统支持; 四轴联动; 制程; 联系; 图档处理试看程序。,西门子四轴卧加后处理程序,支持多种系统与四轴联动
FPGA篮球赛事24秒倒计时计时器设计与实现(基于Verilog与VHDLL的优化对比),基于fpga篮球倒计时24s。 verilog和vhdl两个版本 ,基于FPGA篮球倒计时24s; Verilog版本; VHDL版本,FPGA篮球比赛倒计时24秒系统:Verilog与VHDL双版本实现
论生成式AI在大学生学习中的应用与伦理问题.pdf
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
"S7-200plc与MCGS智能居家控制系统的深度融合:组态画面、IO分配与梯形图接线图原理详解",No.63 S7-200plc和 MCGS智能居家控制系统组态 带解释的梯形图接线图原理图图纸,io分配,组态画面 ,核心关键词:S7-200plc; MCGS智能居家控制系统; 梯形图接线图原理图; io分配; 组态画面。,"S7-200 PLC与MCGS智能居家系统组态及梯形图原理图解析"
方便暖通工程师及板换用户了解艾齐尔板式换热器选型计算,免费使用。
《四层三列堆垛式立体库控制系统:带解释的梯形图接线原理图及IO分配与组态画面详解》,4x3堆垛式立体库4层3列四层三列书架式立体库控制系统 带解释的梯形图接线图原理图图纸,io分配,组态画面 ,立体库; 堆垛式; 控制系统; 梯形图; 接线图; 原理图; IO分配; 组态画面,"立体库控制系统原理图:四层三列堆垛式书架的IO分配与组态画面"
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx