我有以下代码实现monad.我正在尝试使用它来简化以后使用更复杂逻辑的字段设置.
data Rec = Rec {
alpha :: Int,
beta :: Double,
} deriving (Show)
defaultRec = Rec 0 0 0
data Record r = Record { runRecord :: Rec -> (Rec, r) }
instance Monad Record where
return r = Record $ \s -> (s, r)
a >>= b = Record $ \s -> let (q, r) = runRecord a s in runRecord (b r) q
createRecord f = fst $ runRecord f defaultRec
changeAlpha x = Record $ …Run Code Online (Sandbox Code Playgroud) 我希望能够在Emacs中突出显示一个区域,然后按行长度对区域进行排序.
我发现的最接近的代码是我认为按长度排序的代码:
(sort-subr t #'forward-line #'end-of-line nil nil
(lambda (l1 l2)
(apply #'< (mapcar (lambda (range) (- (cdr range) (car range)))
(list l1 l2)))))
Run Code Online (Sandbox Code Playgroud)
但我不知道如何将其变成一个交互式功能,让我通过突出显示一个区域来使用它.有人可以帮忙吗?
以下内容无法编译:
import Language.Haskell.TH
makeAlpha n = [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚错误意味着什么:
Can't derive instances where the instance context mentions
type variables that are not data type parameters
Offending constraint: Show t_d
When deriving the instance for (Show Alpha)
In the Template Haskell quotation
[d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]
In the expression:
[d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]
Run Code Online (Sandbox Code Playgroud)
有可能做这样的派生吗?
我想func FolderExists(path string) bool这会告诉文件夹是否存在且是否可写.我来到这里:
func FolderExists(path string) bool {
info, err := os.Stat(path)
return os.IsExist(err) && info.Mode().IsDir() && info.Mode().???
}
Run Code Online (Sandbox Code Playgroud)
如何判断此文件夹是否可写?我不能简单地检查文件模式权限(例如0200用于用户写入权限),因为那时我必须检查文件的所有者.在Go中有一种直接的方法吗?
对于那些具有UNIX背景的人来说,寻找相当于非常简单的东西:
if [ -d "$n" && -w "$n" ] ; then ... fi
Run Code Online (Sandbox Code Playgroud) 有许多Haskell SQLite绑定,这对我来说意味着使用构建/使用SQLite绑定有许多不同的权衡.我试图阅读其中许多软件包的文档,但过了一段时间它变得模糊,我无法确定选择一个在另一个上的主要权衡.
搜索Hackage发现:
没关系一些"meta"SQLite包.haskelldb-hdbc-sqlite3,haskelldb-hsql-sqlite3,language-sqlite,opaleye-sqlite
希望有人能够成功地做到这一点,并可以帮助我了解如何选择.
我有一个小的Haskell Pipe打印出它运行了多少次:
counterPipe :: Pipe String String IO r
counterPipe = go 0
where
go n = do
await >>= yield
let n' = succ n
liftIO $ putStrLn $ "Chunk " ++ show n'
go n'
Run Code Online (Sandbox Code Playgroud)
我希望能够在处理完最后一个块后打印出一条消息,并可能执行其他任务.我该怎么做呢?
考虑以下两个几乎相同的功能:
buildList 0 = []
buildList n = n : buildList (n - 1)
buildListM 0 = return []
buildListM n = buildListM (n - 1) >>= return . (n :)
Run Code Online (Sandbox Code Playgroud)
Haskell的懒惰方面允许buildList在内存中生成列表而没有太多开销,因为它生成列表的头部然后构建尾部.
但monadic版本buildListM似乎使用更多的内存,n因为它必须首先构建尾部然后在头部前面.
这是在monad中构建列表的好方法,还是有更有效的方法?
我正在尝试pipes通过编写自己的sum函数来学习包,我感到难过.我想不是从使用的效用函数Pipes.Prelude(因为它有sum和fold等功能,这使得它微不足道),并仅作为说明使用该信息Pipes.Tutorial.本教程没有讨论构造函数Proxy,但如果我查看它的源代码sum并fold使用那些构造函数,我想知道是否有可能在sum不知道这些低级细节的情况下编写我的函数.
只要有值可用,我就无法理解这个函数如何能够继续获取值,然后以某种方式将该值返回给用户.我想类型将是:
sum' :: Monad m => Consumer Int m Int
Run Code Online (Sandbox Code Playgroud)
在我看来这可以工作,因为这个函数可以消耗值,直到没有更多,然后返回最后的总和.我会像这样使用它:
mysum <- runEffect $ inputs >-> sum'
Run Code Online (Sandbox Code Playgroud)
但是,函数in Pipes.Prelude具有以下签名:
sum :: (Monad m, Num a) => Producer a m () -> m a
Run Code Online (Sandbox Code Playgroud)
所以我想这是我的第一个障碍.为什么sum函数Producer作为参数而不是>->用于连接?
仅供参考我在danidiaz回答后得到以下结论:
sum' = go 0
where
go n p = next p >>= \x -> case x …Run Code Online (Sandbox Code Playgroud) 在通过GHC扩展工作的同时,我遇到RankNTypes了Haskell学院,其中有以下示例:
main = print $ rankN (+1)
rankN :: (forall n. Num n => n -> n) -> (Int, Double)
rankN f = (f 1, f 1.0)
Run Code Online (Sandbox Code Playgroud)
该文章提供了另一种类型rankN:
rankN :: forall n. Num n => (n -> n) -> (Int, Double)
Run Code Online (Sandbox Code Playgroud)
对差异的解释是"后一个签名需要从n到n的函数用于某些Num n;前一个签名需要从n到n的函数,每个Num n."
我可以理解,前一种类型需要签名是括号中的或更一般的.我不明白后一个签名只需要一个n -> n"某些Num n" 功能的解释.有人可以详细阐述和澄清吗?你如何"阅读"这个以前的签名,这听起来像它的含义?后者的签名是否相同Num n => (n -> n) -> (Int, Double)而不需要forall?