小编Opa*_*Opa的帖子

如何使用带有monads的Kleisli箭头?

在Haskell Control.Arrow文档中,它讨论了Kleisli箭头与monad的关系,但对我来说如何使用它并不明显.我有一个我认为适合箭头的功能,除了它涉及IO monad,所以我认为Kleisli箭头可能有帮助.

使用以下函数返回目录的原始和修改文件名对.

import System.Directory
import System.FilePath

datedFiles target = do
    fns <- getDirectoryContents target
    tms <- mapM (fmap show . getModificationTime) fns
    return $ 
        zip fns $ 
        zipWith replaceBaseName fns $ 
        zipWith (++) (map takeBaseName fns) tms
Run Code Online (Sandbox Code Playgroud)

如果我必须把它画出来,它将是这样的:

在此输入图像描述

我认为它可以从Kleisli箭头的使用中受益,但我不知道如何.有人可以提供指导吗?

monads haskell arrows kleisli

7
推荐指数
2
解决办法
2323
查看次数

如何运行OCaml + Core脚本?

我正在尝试真实世界的OCaml书.它讨论了安装OPAM,然后是OCaml和Jane Street Core.我按照书中的说明正确加载utop,以便自动加载Core.

没有Core,我可以简单地运行一个通用的OCaml脚本而ocaml script.ml无需编译.但是如果脚本使用Core,这不起作用.如果我想在不编译的情况下运行基于Core的OCaml脚本,那么正确的命令是什么?

ocaml

4
推荐指数
1
解决办法
1150
查看次数

如何以管道方式混合Haskell monadic和纯过滤器?

在之前的一个问题中,我试着询问如何通过将它们组合在一起来混合纯函数和monadic函数,但是因为我可能说错了我的问题并且我的例子太简单了,我认为讨论方向错误,所以我认为我会再尝试.

这是一个混合纯和一元过滤器的示例函数.在这个例子中,有一些纯粹的过滤器在monadic过滤器之间排序,试图减少工作量.

findFiles target = 
  getDirectoryContents target                    >>=
  return . filter (not . (=~ "[0-9]{8}\\.txt$")) >>=
  return . filter (=~ "\\.txt$")                 >>=
  filterM doesFileExist                          >>=
  mapM canonicalizePath
Run Code Online (Sandbox Code Playgroud)

以这种方式编写它的好处是纯函数混合使用return,就是从上到下存在可视化的数据.无需临时变量,fmap,<$>等.

理想情况下,我可以摆脱return它,使其更清洁.我有想法使用一些运算符:

(|>=) :: Monad m => a -> (a -> m b) -> m b
a |>= b = (return a) >>= b
Run Code Online (Sandbox Code Playgroud)

但我不知道如何编写此函数以避免运算符优先级问题.这已经存在了吗?它类似于<$>"其他方向".如果没有,我该如何使这个操作符工作?

更一般地说,是否有一种以这种管道方式编写代码的好方法,或者我需要解决fmaps和临时变量,如我之前的问题所述?

haskell pipe operator-keyword

4
推荐指数
1
解决办法
780
查看次数

是否有(返回a)>> = b的标准Haskell函数?

我正在寻找一种方法return从以下函数中删除s:

  naming path = 
    getModificationTime path                       >>=
    return . formatTime defaultTimeLocale "%Y%m%d" >>=
    return . printf "%s_%s" (takeBaseName path)    >>=
    return . replaceBaseName path
Run Code Online (Sandbox Code Playgroud)

我之所以这样构造它的原因是因为它>>=本质上变成了一种管道操作符,并且数据从一行流向下一行.

我想我可以沿着这条线定义一个算子

  a |>= b = (return a) >>= b
Run Code Online (Sandbox Code Playgroud)

得到

  naming path = 
    getModificationTime path              >>=
    formatTime defaultTimeLocale "%Y%m%d" |>=
    printf "%s_%s" (takeBaseName path)    |>=
    replaceBaseName path
Run Code Online (Sandbox Code Playgroud)

但我得到了错误

Precedence parsing error
    cannot mix `|>=' [infixl 9] and `.' [infixr 9] in the same infix expression
Run Code Online (Sandbox Code Playgroud)

解决此问题的最佳方法是什么?更好的是,是否有某种标准的运算符或其他方式可以更容易地以这种方式构造代码?

haskell

3
推荐指数
2
解决办法
194
查看次数

标签 统计

haskell ×3

arrows ×1

kleisli ×1

monads ×1

ocaml ×1

operator-keyword ×1

pipe ×1