在我学习Elixir的过程中,我试图用一个简单的sigil来解析csv.
我已经设法做了一个sigil来做这个,但是我找不到一种方法来使它适用于特殊字符,例如;.
defmodule CommaSigil do
def sigil_v(lines, []), do: parse(lines,",")
def sigil_v(lines, delimiter), do: parse(lines,"#{delimiter}")
defp parse(lines, delimiter) do
lines
|> String.rstrip
|> String.split("\n")
|> Enum.map fn line ->
String.split(line, delimiter)
end
end
end
defmodule Example do
import CommaSigil
def test do
~v"""
hello,world,again
1,2,3
"""
end
def test2 do
~v"""
helloxworldxagain
1x2x3
"""x
end
def test3 do
~v"""
hello;world;again
1;2;3
"""; # <-- Elixir does not care about the ';'
end
end
Example.test
|> IO.inspect
Example.test2
|> …Run Code Online (Sandbox Code Playgroud) 我知道Prolog(逻辑编程)就是返回true和false,并且函数是从列表,数字返回到布尔值的东西.最初,Prolog似乎没有功能的概念,而是依赖于统一,但你可以做以下事情:
?- X is log(42).
X = 3.7376696182833684.
Run Code Online (Sandbox Code Playgroud)
所以似乎存在功能?或者这真的只是隐藏统一部分的某种语法糖?
如果它真的只是语法糖,那么如果我想定义像log2这样的数学"函数",我将如何进行呢?
当然我可以使用统一:
log2(X,Result) :- Result is log(X)/log(2).
Run Code Online (Sandbox Code Playgroud)
但是说我想使用'语法糖函数风格',所以我可以写:
?- X is log2(8).
X = 3.0.
Run Code Online (Sandbox Code Playgroud)
我怎么能在Prolog中做到这一点?
我希望能够在我当前的prolog程序中尽快查找一个术语的存在,而prolog引擎遍历所有术语,直到它最终到达现有术语.
我没有找到任何证据......但我认为给出了
animal(lion).
animal(zebra).
...
% thousands of other animals
...
animal(tiger).
Run Code Online (Sandbox Code Playgroud)
swi-prolog引擎将不得不通过成千上万的动物试图与老虎统一,以确认动物(老虎)在我的prolog数据库中.
在其他语言中,我相信HashSet会解决这个问题,启用O(1)查找...但是我似乎无法在swi-prolog文档中找到任何hashsets或hashtables.
是否有用于hashsets的swi-prolog库,或者我可以使用term_hash\2以某种方式自己构建它?
奖金信息,我很可能不得不查看一些动态添加的数据,要么添加到哈希集数据结构,要么使用assertz
我试图在linux中使用mono建立一个非常简单的测试F#项目,使用Forge设置项目并安装nuget包.Forge创建一个build.fsx使用FAKE 的文件.我试图通过本教程http://fsharp.github.io/FAKE/gettingstarted.html的灵感来调整这个构建文件(为了添加测试).但是,本教程使用C#进行测试,并假定使用.Net作为环境的Windows.我想用F#进行测试,用linux作为环境.
我想我几乎让它工作了,但我从NUnit得到一些神秘的错误信息.运行该build.fsx文件时,我得到以下错误:
...
Invalid argument: -nologo
The value '/home/michel/Documents/FSHARP/UnitTests/test/NUnit.Test.MyTests.dll' is not valid for option '--labels'.
Invalid argument: -xml:./test/TestResults.xml
Running build failed.
Error:
NUnit test failed (255).
---------------------------------------------------------------------
Build Time Report
---------------------------------------------------------------------
Target Duration
------ --------
Clean 00:00:00.0036366
Build 00:00:00.0402828
BuildTest 00:00:00.4911710
Total: 00:00:00.7494956
Status: Failure
---------------------------------------------------------------------
1) Fake.UnitTestCommon+FailedTestsException: NUnit test failed (255).
at Fake.NUnitSequential.NUnit (Microsoft.FSharp.Core.FSharpFunc`2 setParams, IEnumerable`1 assemblies) <0x41d27e50 + 0x0039f> in <filename unknown>:0
at FSI_0001+clo@32-4.Invoke (Microsoft.FSharp.Core.Unit _arg4) <0x41d27dc0 …Run Code Online (Sandbox Code Playgroud) 刚刚在Linux上安装了Swift来检查它.
尝试一个小例子的currying会导致警告curry的语法将来会发生变化,但是我找不到任何关于这个新语法的样子.
我试过的例子:
func do_stuff(x: Int) (y: Int) (z: Int) -> Int {
return (x - y) * z
}
let curry_fun = do_stuff(42)
let x = curry_fun(y: 7)(z: 3)
Run Code Online (Sandbox Code Playgroud)
编译此示例会导致以下警告:
warning: curried function declaration syntax will be removed in a future version of Swift; use a single parameter list
func do_stuff(x: Int) (y: Int) (z: Int) -> Int {
^~~~~~~~~~~~~~~~~~~~~~~~~~
, ,
Run Code Online (Sandbox Code Playgroud)
那么在未来的swift中,currying会是什么样子呢?
我确实尝试了类似的东西 func do_stuff(x: Int, y: Int, z: Int) -> Int... ,但是我找不到用这个函数来干嘛的方法.
我已经定义了我自己的Vect数据类型如下
data MyVect : (n : Nat) -> (t : Type) -> Type where
Nil : MyVect Z t
(::) : (x : t) -> (xs : MyVect n t) -> MyVect (S n) t
Run Code Online (Sandbox Code Playgroud)
然后开始为数据类型实现Foldable接口
Foldable MyVect where
foldr = ?res2
Run Code Online (Sandbox Code Playgroud)
但是当重新加载文件时,Idris投诉
When checking argument t to type constructor Prelude.Foldable.Foldable:
Type mismatch between
Nat -> Type -> Type (Type of MyVect)
and
Type -> Type (Expected type)
Specifically:
Type mismatch between
Nat
and
TypeUnification failure
Run Code Online (Sandbox Code Playgroud)
在稍微摸了一下之后,我猜想我可以通过写作来服从Idris对类型构造函数的要求
Foldable (MyVect n) …Run Code Online (Sandbox Code Playgroud) 给定数据集,例如可能如下所示的CSV文件:
x,y
1,2
1,5
2,1
2,2
1,1
...
Run Code Online (Sandbox Code Playgroud)
我希望创建一个包含给定x的y的列表映射...结果可能如下所示:
{1:[2,5,1], 2:[1,2]}
Run Code Online (Sandbox Code Playgroud)
在python中,这将是一种迫切的方式直接做...并且可能看起来像这样:
d = defaultdict(list)
for x,y in csv_data:
d[x].append(y)
Run Code Online (Sandbox Code Playgroud)
你将如何使用F#中的函数编程技术实现相同的目标? 是否有可能像在给定的python示例中一样使用简单(和可读),只使用功能样式?,或者你必须回归到具有可变数据结构的命令式编程风格.?
注意:这不是一个家庭作业,只是我试图围绕功能编程
编辑:我的结论基于迄今为止的答案
我尝试在一个相对较大的csv文件上计算每个提供的答案,只是为了获得性能的感觉.此外,我用命令式方法做了一个小测试:
let res = new Dictionary<string, List<string>>()
for row in l do
if (res.ContainsKey(fst row) = false) then
res.[fst row] <- new List<string>()
res.[fst row].Add(snd row)
Run Code Online (Sandbox Code Playgroud)
命令式方法在约0.34秒内完成.
我认为李提供的答案是最普遍的FP,但运行时间约为4秒.
丹尼尔给出的答案在约1.55秒内完成.
最后,jbtule给出的答案大约是0.26.(我发现它击败了强制性的方法非常有趣)
我使用'System.Diagnostics.Stopwatch()'进行计时,代码在.Net 4.5中作为F#3.0执行
EDIT2:修复了命令式f#代码中的愚蠢错误,并确保它使用与其他解决方案相同的列表
我想用maplist/3实现的目标可以是跟随伪代码:
maplist(
lambda X: Z/Y=X, to_lower(Z,LC), char_code(L,LC), return L/Y,
['A'/42, 'B'/500],
Res).
Res = ['a'/42, 'b'/500]
Run Code Online (Sandbox Code Playgroud)
我知道可以写例如
maplist(plus(1), [1,2,3,4], Res).
Res = [2,3,4,5].
Run Code Online (Sandbox Code Playgroud)
所以我可以将伪代码定义lambda X: Z/Y=X, to_lower(Z,LC), char_code(L,LC), return L/Y为普通谓词,并在maplist中使用此谓词...
但是,我很好奇是否可以在不创建全新谓词的情况下执行此操作?
我想这样做的原因是因为我觉得阅读更自然,而不是在代码中跳转来找到谓词
如何覆盖内置集合(如map或sequence)中的tostring函数,以便printfn将使用这个新的自定义tostring函数?
我猜它应该是这样的
type seq<'T> with
override xs.Tostring() =
"blabla"
Run Code Online (Sandbox Code Playgroud)
然而,这只是给出错误"类型缩写不能有增加".
然后我看了msdn,发现以下关于类型扩展http://msdn.microsoft.com/en-us/library/dd233211.aspx
它声明我应该能够扩展例如int32和序列如下
type System.Int32 with
member this.FromString( s : string ) =
System.Int32.Parse(s)
type seq<'T> with
/// Repeat each element of the sequence n times
member xs.RepeatElements(n: int) =
seq { for x in xs do for i in 1 .. n do yield x }
Run Code Online (Sandbox Code Playgroud)
第一个例子很好但是对于第二个例子我只是得到一个错误,说"类型缩写不能有成员".
我目前正在使用.Net 4.5.1和F#3.1
如何使用控制台中的fsharpc在linux中编译fsharp应用程序?
我有多个模块,我的应用程序入口点是在Program.fs文件中的经典控制台应用程序样式:
open module A
open module B
open module C
[<EntryPoint>]
let main argv =
...
Run Code Online (Sandbox Code Playgroud)
其中A,B,C在名为A.fs,B.fs和C.fs的文件中...
在Visual Studio中,可以通过在项目视图中重新排列它们来轻松定义编译到文件的顺序,但是我不清楚如何在linux中执行此操作...?
我想我必须以某种方式在控制台中定义顺序
$ fsharpc -o test.exe Program.fs --fileorder:[A.fs,B.fs,C.fs,Program.fs]
Run Code Online (Sandbox Code Playgroud)
我正在使用F#3.1 (目前正在使用新的跨平台VSCode IDE)
我正在阅读一本关于随机模拟的书中的一些R例子,熟悉F#并且不熟悉R -I决定试用R型提供者.
今天我遇到了一个代码片段,我无法弄清楚如何通过R类型提供程序执行.
> Nit = c(0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,6,6,6)
> AOB = c(4.26,4.15,4.68,6.08,5.87,6.92,6.87,6.25,6.84,6.34,6.56,6.52,7.39,7.38,7.74,7.76,8.14,7.22)
> AOBm=tapply(AOB,Nit,mean) #means of AOB
> Nitm=tapply(Nit,Nit,mean) #means of Nit
> fitAOB=lm(AOBm?ns(Nitm,df=2)) #natural spline
Run Code Online (Sandbox Code Playgroud)
相应的F#代码如下所示:
open System
open System.Linq
open RDotNet
open RProvider
open RProvider.``base``
open RProvider.stats
open RProvider.graphics
open RProvider.splines
let mean (l: float seq) = Seq.sum l / float(Seq.length l)
let Nit = [0;0;0;1;1;1;2;2;2;3;3;3;4;4;4;6;6;6]
let AOB = [4.26;4.15;4.68;6.08;5.87;6.92;6.87;6.25;6.84;6.34;6.56;6.52;7.39;7.38;7.74;7.76;8.14;7.22]
let AOBm =
query {
for x in List.zip AOB Nit do
groupBy (snd x) into g …Run Code Online (Sandbox Code Playgroud) 制作地图或记录规范的方式是否比官方规范指南中的方式更简洁?
(defrecord Person [first-name last-name email phone])
(s/def ::first-name string?)
(s/def ::last-name string?)
(s/def ::email ::email-type)
(s/def ::person (s/keys :req-un [::first-name ::last-name ::email]
:opt-un [::phone]))
Run Code Online (Sandbox Code Playgroud)
理想情况下,如果我能写出像这样的东西会很好
(defrecord Person [first-name last-name email phone])
(s/def ::person (s/keys :req-un [:first-name string?
:last-name string?
:email ::email-type]
:opt-un [:phone]))
Run Code Online (Sandbox Code Playgroud) 如果我创建一个简单的lua脚本文件:
test.lua
#!/usr/bin/env lua
local var = math.random(100)
print(var)
Run Code Online (Sandbox Code Playgroud)
它在调用时将始终打印相同的值,即使它在每次调用时确实应该是一个新的随机值.
我的猜测是脚本编译(?)为例如:
#!/usr/bin/env lua
local var = 82
print(var)
Run Code Online (Sandbox Code Playgroud)
(如果82是第一次调用时的随机值)
我可以做什么来确保每次调用脚本时都会编译一个新的(?)字节码(?),这样我就可以在每次执行时得到一个新的随机值剧本?
我添加(?)的原因是我甚至不知道脚本是否完全被编译或者它们被调用时会发生什么,但是这样的事情显然正在发生,因为我总是得到相同的值.