小编Ric*_* T.的帖子

如何知道一个看似纯粹的Haskell界面何时隐藏不安全的操作?

unsafePerformIO最近一直在读,我想问你一件事.我很清楚,真正的语言应该能够与外部环境进行交互,因此unsafePerformIO有些合理.

但是,据我所知,我不知道有什么快速的方法来了解一个看似纯粹的(从类型判断)接口/库是否真的纯粹没有检查代码搜索调用unsafePerformIO(文档可以省略到提到它).我知道只有当你确定引用透明​​度得到保证时才应该使用它,但我想知道它.

haskell purely-functional unsafe-perform-io

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

为什么基于haskell枚举器的IO经常调用sigprocmask?

修订概要

好吧,看起来系统调用肯定与GC有关,而潜在的问题只是GC经常发生.这似乎与splitWhen和pack的使用有关,我可以通过分析来判断.

splitWhen的实现将每个块从惰性文本转换为严格文本,并将它们连接起来,因为它构建了一个块缓冲区.这必然会分配很多.

pack,因为它从一种类型转换为另一种类型,必须分配,并且这是在我的内部循环中,所以这也是有意义的.

原始问题

我在基于haskell枚举器的IO中偶然发现了一些令人惊讶的系统调用活动.希望有人可以对此有所了解.

我一直在玩一个快速perl脚本的haskell版本,我曾经写过几个月,开启和关闭.该脚本从每一行读入一些json,然后打印出特定的字段(如果存在).

这是perl版本,以及我如何运行它.

cat ~/sample_input | perl -lpe '($_) = grep(/type/, split(/,/))' > /dev/null
Run Code Online (Sandbox Code Playgroud)

这是haskell版本(它与perl版本类似地调用).

{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Enumerator as E
import qualified Data.Enumerator.Internal as EI
import qualified Data.Enumerator.Text as ET
import qualified Data.Enumerator.List as EL
import qualified Data.Text as T
import qualified Data.Text.IO as TI
import Data.Functor
import Control.Monad
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.IO as TLI
import System.Environment
import System.IO (stdin, stdout)
import GHC.IO.Handle (hSetBuffering, BufferMode(BlockBuffering))

fieldEnumerator …
Run Code Online (Sandbox Code Playgroud)

performance haskell ghc

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

Haskell或函数式语言的代理?

我正在构建一个多代理系统(MAS)框架来描述Haskell中的Beliefs-Desires-Intents(BDI)代理(即代理是并发的,传达monadic动作).

我在网上搜索过,但除了未完成的工作,在Haskell中指定和控制代理的技术报告外,我无法找到任何关于类似作品的参考.

您是否了解任何可以在Haskell或任何其他功能语言中定义的处理BDI代理的现有实现或研究论文?我的目标是找到可能的相关工作,一切可以管理用功能语言编写的并发智能代理系统.我不需要任何具体的内容,我只想知道我的工作是否与现有方法有共同之处.

编辑:我设法找到对Clojure的引用,这是一种lisp方言,它支持一种非常接近actor模型的代理编程形式,但它并不意味着直接支持BDI代理(一个应该在它上面实现另一个层来获得BDI部分完成我猜).

haskell functional-programming artificial-intelligence agent

6
推荐指数
1
解决办法
2223
查看次数

where子句中的Haskell解析器错误

rs第一节中的定义有什么问题?

palindrome :: [a] -> [a]

palindrome xs = con xs rs
    where con a b = rev (rev a []) b
        rs = rev xs                        -- here
        where rev [] rs = rs
            rev (x:xs) rs = rev xs (x:rs)
Run Code Online (Sandbox Code Playgroud)

我只是在学习Haskell,但它的语法规则让我很困惑.错误消息是

[1 of 1] Compiling Main             ( pelindrome.hs, interpreted )

pelindrome.hs:5:8: parse error on input `rs'
Run Code Online (Sandbox Code Playgroud)

syntax haskell

5
推荐指数
1
解决办法
1万
查看次数

另一种类型的故障

试图了解最终签名是如何推断出来的:

GHCi> :t (+)
(+) :: Num a => a -> a -> a
GHCi> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
GHCi> :t (<*>) (+)
(<*>) (+) :: Num b => (b -> b) -> b -> b
Run Code Online (Sandbox Code Playgroud)

(a' -> a' -> a')必须统一f (a -> b),所以f可能是类型((->) r):

(<*>) :: Applicative ((->) r) => r -> (a -> b) -> (r -> a) …
Run Code Online (Sandbox Code Playgroud)

haskell

5
推荐指数
1
解决办法
157
查看次数

编写对空白敏感的解析器规则,同时从词法分析器中跳过WS

我在处理空白时遇到了一些麻烦。在下面的语法摘录中,我设置了词法分析器,以便解析器跳过空格:

ENTITY_VAR
    : 'user'
    | 'resource'
    ;

INT : DIGIT+ | '-' DIGIT+ ;
ID : LETTER (LETTER | DIGIT | SPECIAL)* ;
ENTITY_ID : '__' ENTITY_VAR ('_w_' ID)?;

NEWLINE : '\r'? '\n';

WS : [ \t\r\n]+ -> skip; // skip spaces, tabs, newlines

fragment LETTER : [a-zA-Z];
fragment DIGIT : [0-9];
fragment SPECIAL : ('_' | '#' );
Run Code Online (Sandbox Code Playgroud)

问题是,我想与形式的变量名进行匹配,以ENTITY_ID使匹配的字符串没有任何空格。像我在这里一样将其编写为词法分析器规则就足够了,但事实是,我想使用解析器规则来代替它,因为我想直接访问这两个标记,ENTITY_VARID分别从我的代码中直接访问并且不要将它们完全挤压在一起ENTITY_ID

有什么想法吗?基本上,任何可以让我直接访问ENTITY_VAR并且ID适合我的解决方案都可以ENTITY_ID作为词法分析器规则保留下来,或者将其移至解析器中。

grammar antlr antlr4

5
推荐指数
1
解决办法
3215
查看次数

`use std::error::Error` 声明会破坏编译

我编写了一个小函数来记录整个堆栈跟踪,如下所示:

fn report_error(error: &Box<dyn std::error::Error>, message: &str) {
    let mut error_msg = Vec::<String>::new();
    error_msg.push(message.to_string());
    if let Some(source) = error.source() {
        error_msg.push("caused by:".into());
        for (i, e) in std::iter::successors(Some(source), |e| e.source()).enumerate() {
            error_msg.push(format!("\t{}: {}", i, e));
        }
    }
    tracing::error!("{}", error_msg.join("\n"));
}
Run Code Online (Sandbox Code Playgroud)

该代码可以在 rustc 1.67.1 上编译并运行良好。但是,一旦我use std::error::Error;在顶部添加声明,编译就会失败,并出现以下错误:

   Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
 --> src/lib.rs:8:63
  |
8 |         for (i, e) in std::iter::successors(Some(source), |e| e.source()).enumerate() {
  |                                                            -- ^^^^^^^^^^ returning this value requires that `'1` must …
Run Code Online (Sandbox Code Playgroud)

rust

5
推荐指数
1
解决办法
92
查看次数

haskell中的递归数据结构:类似prolog的术语

我对Haskell中的递归数据结构有疑问(我目前正在努力学习的语言).

我想用Haskell Prolog之类的术语编码,但我想出的每个解决方案都有不同的缺点,我真的想避免.如果你希望从这个角度来看我的问题,我想找到一种在Haskell类型中编码BNF语法的廉价而优雅的方法.

正如一个提醒,一些序言而言可能是male,sum(2, 3.1, 5.1),btree(btree(0, 1), Variable).

解决方案1

data Term = SConst String
          | IConst Integer
          | FConst Double
          | Var    String
          | Predicate   {predName :: String, predArgs :: [Term]}
Run Code Online (Sandbox Code Playgroud)

使用此解决方案,我可以使用嵌套谓词(因为predArgsTerm),但我无法区分谓词类型签名中的其他术语.

解决方案2

data Term = SConst String
          | IConst Integer
          | FConst Double
          | Var    String

data Predicate = Predicate {predName :: String, predArgs ::[Either Term Predicate}
Run Code Online (Sandbox Code Playgroud)

在这个变体中,我可以清楚地区分谓词和基本术语,但是列表中的Either类型在predArgs后面的代码中管理会非常麻烦(我想......我是Haskell的新手).

解决方案3

data Term = SConst String
          | …
Run Code Online (Sandbox Code Playgroud)

grammar haskell bnf recursive-datastructures

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

Haskell部分应用函数,派生类型

在GHCI前奏>使用:t中查找函数的类型:

(.) :: (b -> c) -> (a -> b) -> a -> c

(:) :: a -> [a] -> [a]

((.)(:)) :: (a -> b) -> a -> [b] -> [b]   -- (what happened here?)
Run Code Online (Sandbox Code Playgroud)

我理解单个函数的结果,但是当部分应用时我没有.

地图的类型是什么?我在这个页面上找到了答案,如何以代数方式进行.但是我在使用相同的方法时遇到了问题((.)(:)).

当你想知道什么类型的方法是((.)(:))什么?有没有一种思维方式可以用于函数的任何部分应用?

提前致谢.

haskell

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

如何很好地评估嵌套的StateT和ErrorT monad?

我在程序的不同级别有两个类型的控件结构声明.最下面的是Agent一个StateTIO能力的.第二个是StateT具有Agent功能的另一个,第三个是(Plan)是一个ErrorT.

type Agent = StateT AgentState IO
type Plan = ErrorT PlanError (StateT PlanState Agent)
Run Code Online (Sandbox Code Playgroud)

评估a的最佳方法是Plan什么?我写了下面的代码,但它不是很少,因为有大量的嵌套runStateTrunErrorT调用.

foo :: Plan ()
defaultAgentState :: AgentState
runStateT (runStateT (runErrorT foo) (PlanState 0)) defaultAgentState
Run Code Online (Sandbox Code Playgroud)

有更简单/更好的东西吗?

monads haskell monad-transformers

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