小编lef*_*out的帖子

OCaml是否有融合法

最近我正在阅读一些涉及Haskell的函数式编程书籍.

看来Haskell非常喜欢"模块化程序",例如,

f :: (Integer,Integer) -> Integer
f = sum . map sq . filter . odd . between
Run Code Online (Sandbox Code Playgroud)

即使可以写出相同的功能

f' (m, n) = go m
  where go m | m > n = 0
             | otherwise = go (m + 1) + if odd m then sq m else 0
Run Code Online (Sandbox Code Playgroud)

"融合法"也很受欢迎并被使用(http://www.cs.ox.ac.uk/ralf.hinze/publications/IFL10.pdf)


我不是OCaml专家,但我会使用fold_leftfold_right尽可能简单高效(例如,无论如何我必须扫描整个列表并且不会停在中间).

但是,在大多数情况下,我将使用"模式匹配"编写显式递归代码.

另外我在github中读了很多OCaml项目,显式递归似乎很常见.

另外,我从未听说过OCaml的融合法.


我的问题是

  1. OCaml是否与上面Haskell中所示的模块化程序相同?
  2. OCaml也有融合法吗?
  3. 如果我想成为OCaml专业人士,我是否应该真正关心或学习Haskell的融合法?

ocaml haskell functional-programming

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

应用函子的目的是什么?

当具有以下签名的函数有用时,任何人都可以分享良好的现实生活情况吗?

f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)

我无法真正看到我需要的东西,比如来自Learn-you-a-haskell的教科书示例 [(+),(*)] <*> [1,2] <*> [3,4]

haskell functional-programming

4
推荐指数
2
解决办法
250
查看次数

具有复合/多参数类型构造函数的Haskell类型签名

我发现了这些类型的签名:

x :: a b -> Int
x f = 3

y :: a b c -> Int
y f = 3

z :: a b c d -> Int
z f = 3

> x [1] -- 3
> y (1, 2) -- 3
> z (1, 2, 3) -- 3
Run Code Online (Sandbox Code Playgroud)

基本上:

  1. x只接受一个带有1个参数或更多参数的类型构造函数的值.
  2. y只接受一个包含2个或更多参数的类型构造函数的值.
  3. z只接受一个包含3个或更多参数的类型构造函数的值.

它们是有效的,但我不确定它们的含义以及它们可以用于什么.

它们似乎与类型构造函数上的多类型概念或多态相关,但是基于类型构造函数接受的许多参数强制执行不变量.

polymorphism haskell types

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

Endofunction为Monoid

我正在尝试这个(用于学习目的):

{-# LANGUAGE FlexibleInstances #-}

instance Monoid (a -> a) where
  mempty = id
  mappend f g = f . g
Run Code Online (Sandbox Code Playgroud)

期望id <> id等于id . id

但是,(id <> id) 1我收到此错误:

Non type-variable argument in the constraint: Monoid (a -> a)
Run Code Online (Sandbox Code Playgroud)

我应该改变什么来运行它?

这只是为了更好地理解monoids和Haskell类型类,而不是用于任何实际用途.

haskell monoids

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

为什么这个类型定义是非法的?

我正在为一种小型编程语言编写一个解释器,AST 看起来像这样:

\n
data Value a = IntVal a Int | FloatVal a Float\ndata Expr a = AddExpr a (Value a) (Value a) | MulExpr a (Value a) (Value a)\n
Run Code Online (Sandbox Code Playgroud)\n

我使用参数a来存储每个术语的行号。有些函数采用带注释的术语,有些函数采用空术语(用 替换aunit,如下所示:

\n
myFunction :: Value Int -> ...\nmyFunction = ...\n\nmyOtherFunction :: Value () -> ...\nmyOtherFunction = ...\n
Run Code Online (Sandbox Code Playgroud)\n

然而,我发现这个替代方案更清晰一些:

\n
type Annotated b = b Int\ntype Bare b = b ()\n
Run Code Online (Sandbox Code Playgroud)\n

然后,我可以像这样重写前两个函数:

\n
myFunction :: Annotated Value -> ...\nmyFunction = ...\n\nmyOtherFunction …
Run Code Online (Sandbox Code Playgroud)

haskell

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

为什么 Haskell 数字文字需要以数字开头和结尾?

Haskell 98 报告中

浮动文字必须包含小数点前后的数字;这可确保小数点不会被误认为是点字符的其他用途。

这可能还有什么用处?我无法想象任何这样的合法表达。

(为了澄清动机:我知道很多人都喜欢9.00.7一直在不需要的情况下写数字,但我不能完全与自己交朋友。我可以0.7选择更紧凑但其他更好的.7,但是重写的尾随零对我来说是错误的,除非它们表达的某个数量精确到十分之一,这在 Haskell 让我写9.0数字的场合很少见。)


我忘了在没有空格的情况下编写函数组合是合法的!这当然是一种可能性,尽管可以通过贪婪地解析浮动文字来避免这个问题,例如replicate 3 . pred$8? ((replicate 3) . pred) 8但是replicate 3.pred$8(replicate 3.0 pred)8.


有没有其中一个整数文字表达需要直接旁边站立.,没有空白?

floating-point haskell literals rational-numbers

3
推荐指数
1
解决办法
1126
查看次数

这是合法使用"未定义"还是有更好的方法?

我最近一直在玩MySQL-Simple.试图为该库提供一些全面的例子.我想将ID与我想要存储的实际记录分开.要为此Entity数据类型实现QueryResults的错误情况,我需要此数据类型实际使用的字段数量.因此我介绍了一个Arity类型类(很容易出错,特别是在数据发生变化时).我也在undefined这里用来调用方法的正确实例arity.

我在几个例子中看过这样的东西,但我对undefined这里的使用感到不安.有没有更好的方法来做到这一点?

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE BangPatterns #-}
module Main where

import Database.MySQL.Simple
import Database.MySQL.Simple.QueryResults
import Database.MySQL.Simple.QueryParams
import Database.MySQL.Simple.Result
import Database.MySQL.Simple.Param

connectInfo :: ConnectInfo
connectInfo = defaultConnectInfo { connectUser = "dbuser" }

data Person = Person { personName :: String
                     , personAge  :: Int
                     } deriving Show

class Arity a where
  arity :: a -> Int

instance Arity Person where
  arity _ = 2

instance QueryResults Person where
  convertResults [fname, …
Run Code Online (Sandbox Code Playgroud)

mysql haskell

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

git可以自动将提交分成单个帅哥吗?

如前面的问题所述,您可以将提交拆分为较小的补丁.但是,这些答案建议git add -p,这可以完成工作,但如果我想要的是每个块的一次提交,则按照文件中的给定顺序进行繁琐.有没有办法实现这一点,自动?

git bash

3
推荐指数
1
解决办法
189
查看次数

Haskell从文件IO返回惰性字符串

在这里,我又回来了(对我而言)我最新杰作的奇怪行为......

此代码应该读取文件,但它不会:

readCsvContents :: String -> IO ( String )
readCsvContents fileName = do
     withFile fileName ReadMode (\handle -> do
          contents <- hGetContents handle
          return contents
          )

main = do
    contents <- readCsvContents "src\\EURUSD60.csv"
    putStrLn ("Read " ++ show (length contents) ++ " Bytes input data.")
Run Code Online (Sandbox Code Playgroud)

结果是

Read 0 Bytes input data.
Run Code Online (Sandbox Code Playgroud)

现在我改变了第一个函数并添加了一个putStrLn:

readCsvContents :: String -> IO ( String )
readCsvContents fileName = do
     withFile fileName ReadMode (\handle -> do
          contents <- hGetContents handle
          putStrLn ("hGetContents gave …
Run Code Online (Sandbox Code Playgroud)

file-io haskell lazy-evaluation

3
推荐指数
1
解决办法
260
查看次数

通过独立派生获得

我不确定我在这里做错了什么:

data Vector2D u = Vector2D { 
    _x :: u, 
    _y :: u 
} deriving stock (Show, Eq, Functor, Foldable, Traversable)

{-# INLINE addVector2 #-}
addVector2 :: (Additive a) => Vector2D a -> Vector2D a -> Vector2D a 
addVector2 (Vector2D { _x = x1, _y = y1 }) (Vector2D { _x = x2, _y = y2 }) = 
    Vector2D { _x = x1 + x2, _y = y1 + y2 }

instance (Additive a) => Additive (Vector2D a) where
    (+) …
Run Code Online (Sandbox Code Playgroud)

haskell deriving

3
推荐指数
1
解决办法
524
查看次数