Haskell:如何计算此公式? `返回+110月10日10`

如何解决Haskell:如何计算此公式? `返回+110月10日10`

这是关于通过Applicative和Monad组合两个简单的算术运算符(两个部分函数)。 到目前为止,我对此大致了解。

-- ┌──────────────────────────────────────┐  
-- | instance Applicative ((->) r) where  |                                           
-- |   pure = const                       |                                           
-- |   (<*>) f g x = f x (g x)            |  (1)                                          
-- |   liftA2 q f g x = q (f x) (g x)     |                                         
-- |                                      |       
-- | instance Monad ((->) r) where        |                                           
-- |   f >>= k = \r -> k (f r) r          |  (2)                                                                         
-- └──────────────────────────────────────┘

λ> (+) <*> (*2) $ 10  
  -- Type check: 
  (<*>) ::  f     (a -> b) -> f      a  -> f      b
           (-> r) (a -> b) -> (-> r) a  -> (-> r) b
           (r ->   a -> b) -> (r ->  a) -> (r ->  b)
           ---------------    ---------
           (+) ~ f            (*2) ~ g      r ~ x (10)

  -- Actual calcuation: by (1)
  f x (g x) = (+) 10 ((*2) 10) = (+) 10 20 = 30 

λ> (*2) >>= (+) $ 10  -- 30
  -- Type check: 
  (>>=) ::  m     a    ->  a  -> m     b  ->  m     b
           (-> r) a    -> (-> r) a  -> b  -> (-> r) b
           (r  -> a)   -> (a  -> r  -> b) -> (r ->  b)
           ---------      ---------------
           (*2) ~ f       (+) ~ k             r ~ 10

  -- Actual calculation: by (2)
  k (f r) r = (+) ((*2) 10) 10 = (+) 20 10 = 30 

但是,当我试图将这些东西应用于某个结构(也许)时,我被卡在了上面。 (我在卡住的行尾标记了“ HERE”。)

-- ┌────────────────────────────────────────────────┐   
-- | instance Applicative Maybe where               |                                     
-- |     pure = Just                                |                    
-- |     Just f  <*> m       = fmap f m             |                                       
-- |     Nothing <*> _m      = Nothing              |                                      
-- |     liftA2 f (Just x) (Just y) = Just (f x y)  |                                                  
-- |     liftA2 _ _ _ = Nothing                     |                               
-- |     Just _m1 *> m2      = m2                   |                                 
-- |     Nothing  *> _m2     = Nothing              |                                      
-- |                                                |     
-- | instance  Monad Maybe  where                   |                                 
-- |     (Just x) >>= k      = k x                  |                                  
-- |     Nothing  >>= _      = Nothing              |                                      
-- |     (>>) = (*>)                                |                                                            
-- └────────────────────────────────────────────────┘

λ> Just 10 >>= return . (+1)   -- Just 11
  -- Type check:
  (>>=) ::  m     a    ->  a  -> m     b  ->  m     b
            ----------     --------------
            Just 10        return . (+1) :: a -> m b  
        so,m ~ Maybe,a ~ Int
  Just 10 >>= return . (+1) :: m     b 
                               Maybe Int 
  
  -- Actual calculation:
  Just 10 >>= return . (+1) = return . (+1) $ 10
                            = Just   . (+1) $ 10
                            = Just 11

λ> Just >>= return (+1) $ 10   -- 11
  -- This is point-free style
     I don't get it.
  -- Type check:
  (>>=) ::  m     a    ->     a  -> m     b  ->  m     b
            ----------        --------------
            (-> a) (Maybe a)  m (a -> a)   <==== HERE! 
                                           I can't derive the correct type. 

  -- Actual calculation:                   <==== and HERE!
  m >>= f   = \x -> f (m x) x              <==== How can this formula be derived?
            = (return (+1)) (Just 10) 10   <==== How can this be calculated?

Monad表达式中有无点样式。我不知道与以前的简单算术表达式一样,如何推导类型并获得结果?

非常感谢。


感谢您的出色回答,尼尔。在您的帮助下,我可以发现我的思想和代码出了什么问题。但是我仍然无法正确获得Just >>= return (+1)的最终类型。我更新了问题,并试图推断出问题的类型。我知道我的类型推导是错误的。我能否获得更多帮助,以找到错误的部分并进行修复?

-- Type check: Incorrect
(>>=) ::  m     a    ->     a  ->  m    b  ->  m     b
         (-> r) a    ->    (-> r)  a -> b  -> (-> r) b
         --------          --------------
         f                 k                  \r -> k (f r) r
         m                 f                  \r -> m (f r) r          
         (-> d) (Maybe d)  (-> r) (n -> n)
     so,a ~ Maybe d
         a ~ n,b ~ n  -- This means a,b,n are all the same type.
                       -- Character a,b can be interchangeable. 
Just >>= return (+1) :: (-> r) b  
                      = (-> r) a          -- by `a ~ b`
                      = (-> r) (Maybe d)  -- by `a ~ Maybe d` 
                                          -- HERE: Is this right?  
                                             Should this be `(-> r) n`?
                      = a -> Maybe b      -- by changing characters
               HERE: WRONG RESULT TYPE??? It must be `a -> a` not `a -> Maybe a` 

-- Actual calcuation:
Moand instance for function (`(-> r)`) type here (I got)
m >>= f = \x -> f (m x) x
        = return (+1) (Just 10) 10
        = return (+1) (Just 10) $ 10
        = const  (+1) (Just 10) $ 10  -- by (1),pure = const
        = (+1) $ 10                   -- 'Just 10' was ignored by 'const (pure)' function.
        = (+) 10 = 11

非常感谢。

解决方法

Just >>= return (+1) $ 10

Just是一个函数r -> Maybe r,因此使用了函数monad ((->) r),其简化为

return (1+) (Just 10) 10

因为这是>>= monad的((->) r)的定义(就像您在帖子的顶部f >>= k = \r -> k (f r) r中给出的那样)。

现在,return (1+)应用于Just 10,所以它也是一个函数,

return :: Monad m => a          -> m        a
(1+) :: Num m =>   n -> n
return (1+) :: (Monad m,Num n) => m     (n -> n)
                         Num n  => (r -> (n -> n))
Just 10 :: (Num i => Maybe i) ~     r

对于功能,return == const,所以我们有

const (1+) (Just 10) 10
===
(1+) 10
===
11

您的另一个问题是((->) r)单子m >>= f = \x -> f (m x) x会如何发展? (您确实注意到,它与顶部的f >>= k = \r -> k (f r) r定义相同,直到重命名了一些变量,对吗?)

答案是,因为类型合适:

(>>=)    ::  m     a  -> (a -> m     b ) -> m     b
         ~   (r -> a) -> (a -> (r -> b)) -> (r -> b)
(>>=)        m           f                   x  = b
    where
        mx = m x       :: a
        f_mx = f mx    ::       r -> b
        b = f_mx x     ::            b

edit:让我们尝试毫无疑问地推导Just >>= return (+1)的类型,就像编译器那样以纯机械方式。我们将使用类型派生的主要规则,该规则与逻辑中的Modus Ponens规则相对应:

        A     :: a
     F        :: t -> b
    --------------------
     F  A     ::      b,t ~ a

诀窍是从一开始就使用所有不同的类型变量,因此我们什至没有机会将它们混合使用:

 -- Just >>= return (+1)  ===  (>>=) Just (return (+1))

return      ::  Monad f =>           d    -> f    d
       (+1) ::           Num n =>  n -> n
                         ----------------
return (+1) :: (Monad f,Num n) =>           f (n ->  n)
---------------------------------------------------------
(>>=)  ::    Monad m => m        a -> (a    -> m      b ) -> m      b
      Just  ::          (->) c (Maybe c)
                        ----------------
                 m ~ (->) c,a ~ Maybe c
                 --------------------------
(>>=) Just  ::   Monad ((->) c) => (Maybe c -> (->) c b ) -> (->) c b
             ~   Monad ((->) c) => (Maybe c -> (c ->  b)) -> (c ->  b)
                                   ---------------------- 
return (+1) :: (Monad f,Num n) =>           f (n ->  n)
                                   ---------------------- 
                          f ~ (->) (Maybe c),(n ->  n) ~
                                               (c ->  b)
(>>=) Just (return (1+)) ::
      (Monad ((->) c),Monad ((->) (Maybe c))  =>             c ->  b
                      ~  Num n                 =>             n ->  n

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res