小编ama*_*loy的帖子

Clojure项目值得一读?

学习新语言的最佳方法是阅读结构良好且记录完备的项目,这些项目以正确的方式使用语言结构.

什么是最好的clojure回购阅读和从中学习?

clojure

10
推荐指数
1
解决办法
226
查看次数

如何让默认值来自数据库?

为什么user对象仍具有Nothing用于createdAtupdatedAt?为什么这些字段没有被数据库分配?

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
User
  email String
  createdAt UTCTime Maybe default=CURRENT_TIME
  updatedAt UTCTime Maybe default=CURRENT_TIME
  deriving Show
|]

main = runSqlite ":memory:" $ do
  runMigration migrateAll
  userId <- insert $ User "saurabhnanda@gmail.com" Nothing Nothing
  liftIO $ print userId
  user <- get userId
  case user of
    Nothing -> liftIO $ putStrLn ("coulnt find userId=" ++ (show userId))
    Just u -> liftIO $ putStrLn ("user=" ++ (show user))
Run Code Online (Sandbox Code Playgroud)

输出:

UserKey {unUserKey …
Run Code Online (Sandbox Code Playgroud)

haskell yesod

10
推荐指数
2
解决办法
743
查看次数

布尔值(p ^ q)和(p!= q)之间有有用的区别吗?

Java有两种检查两个布尔值是否不同的方法。您可以将它们与!=或与^(xor)进行比较。当然,这两个运算符在所有情况下都会产生相同的结果。尽管如此,将两者都包括在内还是很有道理的,例如,在“异或”与“不相等”之间有什么区别?。对于开发人员而言,根据上下文选择一个相对于另一个更有意义-有时“恰好是这些布尔值之一”读起来更好,而有时“这两个布尔值不同”则更好地传达了意图。因此,也许使用哪个应该是口味和风格的问题。

令我惊讶的是javac并没有完全一样对待它们!考虑此类:

class Test {
  public boolean xor(boolean p, boolean q) {
    return p ^ q;
  }
  public boolean inequal(boolean p, boolean q) {
    return p != q;
  }
}
Run Code Online (Sandbox Code Playgroud)

显然,这两种方法具有相同的可见行为。但是它们具有不同的字节码:

$ javap -c Test
Compiled from "Test.java"
class Test {
  Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public boolean xor(boolean, boolean);
    Code:
       0: iload_1
       1: iload_2
       2: ixor
       3: ireturn

  public boolean inequal(boolean, boolean);
    Code:
       0: iload_1
       1: …
Run Code Online (Sandbox Code Playgroud)

java performance

10
推荐指数
1
解决办法
182
查看次数

在Clojure中通过"窗口"谓词对seq进行分区

我希望将seq"chunk"为subseqs,与partition-by相同,不同的是该函数不应用于每个单独的元素,而是应用于一系列元素.

所以,例如:

(gather (fn [a b] (> (- b a) 2)) 
        [1 4 5 8 9 10 15 20 21])
Run Code Online (Sandbox Code Playgroud)

会导致:

[[1] [4 5] [8 9 10] [15] [20 21]]
Run Code Online (Sandbox Code Playgroud)

同样:

(defn f [a b] (> (- b a) 2))
(gather f [1 2 3 4]) ;; => [[1 2 3] [4]]
(gather f [1 2 3 4 5 6 7 8 9]) ;; => [[1 2 3] [4 5 6] [7 8 9]]
Run Code Online (Sandbox Code Playgroud)

我的想法是我将列表的开头和下一个元素应用于函数,如果函数返回true,我们将列表的当前头部分区分割到新的分区.

我写过:

(defn gather
  [pred? lst] …
Run Code Online (Sandbox Code Playgroud)

clojure

9
推荐指数
1
解决办法
1039
查看次数

如何用foldl实现zip(用急切的语言)

我最近认识的一个Clojure程序员说过用Clojure reduce(就是Haskell的foldl')来实现很多序列函数是可能的,但遗憾的是没有办法实现(map list xs ys)(就是Haskell的zip)reduce.

现在,我已经读到了折叠的普遍性,所以我很确定这不是真的:当然zip是可能的foldr,如果不可能,我会感到惊讶foldl.出于讨论的目的,我们忽略了与之foldl相比的渴望问题foldr:想象我们拥有无限的记忆并且只能使用有限的序列.

所以,我使用Haskell代码用foldr实现zip,并将其翻译成Clojure,尽力调整foldr和foldl之间的区别:

(defn zip [xs ys]
  (letfn [(done [_] [])
          (step [z x]
            (fn [ys]
              (if (empty? ys)
                []
                (conj (z (rest ys)) [x (first ys)]))))]
    ((reduce step done xs) ys)))
user> (zip [1 2] '[a b c]) ;=> [[1 b] [2 a]]
Run Code Online (Sandbox Code Playgroud)

事实上,我们确实从xs和ys中得到了元素对,但是乱序:xs的第一个元素与ys的最后一个元素配对,依此类推.我可以看到问题的原因:我们生成的函数从左边开始消耗ys,但是最外面的闭包(首先调用)已经关闭了xs的最后一个元素,所以它不能在右边配对它们订购.

我认为修复是以某种方式从内到外构建闭包,但我真的不知道如何做到这一点.我很乐意接受Haskell或Clojure的解决方案.

我希望找到一个表格的解决方案zip = foldl f x,这样我就可以说它只是"减少".当然我可以反转其中一个列表,但最后它zip xs …

haskell functional-programming clojure fold

9
推荐指数
1
解决办法
918
查看次数

How do i check if a string can be parsed to a certain type in Haskell?

So I have my own data type in haskell defined like this:

data Token = Num Double | Op String
Run Code Online (Sandbox Code Playgroud)

I want to make a function that converts a list of strings into a list of tokens. E.g.

toTokenList ["2","+","3"]
> [Num 2.0, Op "+", Num 3.0]
Run Code Online (Sandbox Code Playgroud)

How would I go about doing this?

I have implemented a function that converts a type Double into a Token type and another one that converts a String to a Token type. Can …

haskell

8
推荐指数
1
解决办法
154
查看次数

为什么“强制”不隐式地将 Compose 应用于这些函数?

考虑这种类型:

\n
data Vec3 = Vec3 {_x, _y, _z :: Int}\n
Run Code Online (Sandbox Code Playgroud)\n

我有一些函数都采用相同的输入,并且可能无法计算字段:

\n
data Input\ngetX, getY, getZ :: Input -> Maybe Int\n
Run Code Online (Sandbox Code Playgroud)\n

我可以编写一个函数来尝试所有这三个字段构造函数:

\n
v3 :: Input -> Maybe Vec3\nv3 i = liftA3 Vec3 (getX i) (getY i) (getZ i)\n
Run Code Online (Sandbox Code Playgroud)\n

但必须将输入传递i三次左右,这有点烦人。函数本身就是一个应用函子,因此可以替换foo x = bar (f x) (g x) (h x)foo = liftA3 bar f g h

\n

在这里,我的barliftA3 Vec3,所以我可以写

\n
v3' :: Input -> Maybe Vec3\nv3' = …
Run Code Online (Sandbox Code Playgroud)

haskell applicative

8
推荐指数
1
解决办法
167
查看次数

如何使用递归方案来“cata”两种相互递归类型?

我从这种带有标记节点的叶值树开始:

\n
type Label = String\ndata Tree a = Leaf Label a \n            | Branch Label [Tree a]\n
Run Code Online (Sandbox Code Playgroud)\n

我想在这棵树上写一些折叠,它们都采用变形的形式,所以让我们recursion-schemes为我进行递归遍历:

\n
{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable, TemplateHaskell, TypeFamilies #-}\nimport Data.Functor.Foldable.TH (makeBaseFunctor)\nimport Data.Functor.Foldable (cata)\n\ntype Label = String\ndata Tree a = Leaf Label a \n            | Branch Label [Tree a]\nmakeBaseFunctor \'\'Tree\n\nallLabels :: Tree a -> [Label]\nallLabels = cata go\n  where go (LeafF l _) = [l]\n        go (BranchF l lss) = l : concat lss\n
Run Code Online (Sandbox Code Playgroud)\n

一切都很好:我们可以遍历一棵树:

\n
\xce\xbb> allLabels …
Run Code Online (Sandbox Code Playgroud)

haskell recursion-schemes

8
推荐指数
1
解决办法
268
查看次数

在Clojure中使用延迟卷积fn的麻烦

我正在编写一些信号处理软件,我开始编写一个离散卷积函数.

这适用于前一万个左右的值列表,但随着它们变大(例如,100k),我开始得到StackOverflow错误,当然.

不幸的是,我在将命令式卷积算法转换为递归和懒惰版本时遇到了很多麻烦,实际上使用速度足够快(至少有一点优雅也很好).

我也不是100%确定我完全没有这个功能,但是 - 如果我错过了什么/做错了什么,请告诉我.我认为这是正确的.

(defn convolve
  "
    Convolves xs with is.

    This is a discrete convolution.

    'xs  :: list of numbers
    'is  :: list of numbers
  "
  [xs is]
  (loop [xs xs finalacc () acc ()]
    (if (empty? xs)
      (concat finalacc acc)
      (recur (rest xs)
             (if (empty? acc)
               ()
               (concat finalacc [(first acc)]))
             (if (empty? acc)
               (map #(* (first xs) %) is)
               (vec-add
                (map #(* (first xs) %) is)
                (rest …
Run Code Online (Sandbox Code Playgroud)

functional-programming signal-processing clojure convolution

7
推荐指数
1
解决办法
1013
查看次数

Clojure中的固定长度堆栈结构

什么是固定长度堆栈的最佳数据结构(我最初称之为队列,但我想要的是一个堆栈),其中项目被添加到前面,每次将项目添加到前面时,项目将从结束?从前面也可以访问各种长度的子向量.我正在使用矢量,现在考虑clojure.lang.PersistentQueue和手指树.

编辑,澄清,例如:

> (def q (queue [1 2 3 4]))
[1 2 3 4]
> (push q 9 8 7)
[7 8 9 1]
> (peek (push q 9 8 7))
7
Run Code Online (Sandbox Code Playgroud)

edit2:感谢你到目前为止所有的答案,这已经变成了回归基础和阅读Clojure的乐趣的练习,例如学习subvec的subvec保留对第一个subvec的向量的引用,而像(vec(cons) x(subvec ...如果反复使用会产生对所有中间子集的引用.鉴于此,如何推送基于矢量的队列的推送?:

(defn push [v i n] (if (>= (count v) n) (conj (subvec v 1 n) i) (conj v i) ) )
Run Code Online (Sandbox Code Playgroud)

然后可以通过rseq访问生成的向量,我相信它对向量很快(由于它使用索引偏移?)

queue clojure

7
推荐指数
1
解决办法
1464
查看次数