我unsafePerformIO最近一直在读,我想问你一件事.我很清楚,真正的语言应该能够与外部环境进行交互,因此unsafePerformIO有些合理.
但是,据我所知,我不知道有什么快速的方法来了解一个看似纯粹的(从类型判断)接口/库是否真的纯粹没有检查代码搜索调用unsafePerformIO(文档可以省略到提到它).我知道只有当你确定引用透明度得到保证时才应该使用它,但我想知道它.
修订概要
好吧,看起来系统调用肯定与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) 我正在构建一个多代理系统(MAS)框架来描述Haskell中的Beliefs-Desires-Intents(BDI)代理(即代理是并发的,传达monadic动作).
我在网上搜索过,但除了未完成的工作,在Haskell中指定和控制代理的技术报告外,我无法找到任何关于类似作品的参考.
您是否了解任何可以在Haskell或任何其他功能语言中定义的处理BDI代理的现有实现或研究论文?我的目标是找到可能的相关工作,一切可以管理用功能语言编写的并发智能代理系统.我不需要任何具体的内容,我只想知道我的工作是否与现有方法有共同之处.
编辑:我设法找到对Clojure的引用,这是一种lisp方言,它支持一种非常接近actor模型的代理编程形式,但它并不意味着直接支持BDI代理(一个应该在它上面实现另一个层来获得BDI部分完成我猜).
haskell functional-programming artificial-intelligence agent
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) 试图了解最终签名是如何推断出来的:
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) 我在处理空白时遇到了一些麻烦。在下面的语法摘录中,我设置了词法分析器,以便解析器跳过空格:
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_VAR并ID分别从我的代码中直接访问并且不要将它们完全挤压在一起ENTITY_ID。
有什么想法吗?基本上,任何可以让我直接访问ENTITY_VAR并且ID适合我的解决方案都可以ENTITY_ID作为词法分析器规则保留下来,或者将其移至解析器中。
我编写了一个小函数来记录整个堆栈跟踪,如下所示:
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) 我对Haskell中的递归数据结构有疑问(我目前正在努力学习的语言).
我想用Haskell Prolog之类的术语编码,但我想出的每个解决方案都有不同的缺点,我真的想避免.如果你希望从这个角度来看我的问题,我想找到一种在Haskell类型中编码BNF语法的廉价而优雅的方法.
正如一个提醒,一些序言而言可能是male,sum(2, 3.1, 5.1),btree(btree(0, 1), Variable).
data Term = SConst String
| IConst Integer
| FConst Double
| Var String
| Predicate {predName :: String, predArgs :: [Term]}
Run Code Online (Sandbox Code Playgroud)
使用此解决方案,我可以使用嵌套谓词(因为predArgs是Term),但我无法区分谓词类型签名中的其他术语.
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的新手).
data Term = SConst String
| …Run Code Online (Sandbox Code Playgroud) 在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)
我理解单个函数的结果,但是当部分应用时我没有.
地图的类型是什么?我在这个页面上找到了答案,如何以代数方式进行.但是我在使用相同的方法时遇到了问题((.)(:)).
当你想知道什么类型的方法是((.)(:))什么?有没有一种思维方式可以用于函数的任何部分应用?
提前致谢.
我在程序的不同级别有两个类型的控件结构声明.最下面的是Agent一个StateT有IO能力的.第二个是StateT具有Agent功能的另一个,第三个是(Plan)是一个ErrorT.
type Agent = StateT AgentState IO
type Plan = ErrorT PlanError (StateT PlanState Agent)
Run Code Online (Sandbox Code Playgroud)
评估a的最佳方法是Plan什么?我写了下面的代码,但它不是很少,因为有大量的嵌套runStateT和runErrorT调用.
foo :: Plan ()
defaultAgentState :: AgentState
runStateT (runStateT (runErrorT foo) (PlanState 0)) defaultAgentState
Run Code Online (Sandbox Code Playgroud)
有更简单/更好的东西吗?