如何在单声道 (OS X) 中加载 .fsx 文件,并使用内部 types\functions?
How to load a .fsx file in mono (OS X), and use the internal types\functions?
我通过 brew install mono
在 OS X 上安装了单声道,当我在终端中 运行 fsharpi
时加载了 F# v.4.01。
我有一个 .fsx
文件,其中定义了一些类型和函数。我希望在 fsi
(fsharpi
的别名)中交互使用它们。为此,我启动了 fsi
和 运行 #load "pc.fsx;;"
- 文件被加载和编译,我看到了通用命名空间下的所有类型定义和函数类型。出于某种原因,REPL 无法识别自定义类型(因此我无法使用类型构造函数)和函数,因此我收到错误 FS0039:The value or constructor '<insert type or function name>' is not defined
。我该如何克服这个问题?
编辑:
该文件名为 Temp.fsx
,内容包含在名为 Temp
.
的模块中
文件内容:
module Temp =
open System
/// Type that represents Success/Failure in parsing
type Result<'a> =
| Success of 'a
| Failure of string
/// Type that wraps a parsing function
type Parser<'T> = Parser of (string -> Result<'T * string>)
/// Parse a single character
let pchar charToMatch =
// define a nested inner function
let innerFn str =
if String.IsNullOrEmpty(str) then
Failure "No more input"
else
let first = str.[0]
if first = charToMatch then
let remaining = str.[1..]
Success (charToMatch,remaining)
else
let msg = sprintf "Expecting '%c'. Got '%c'" charToMatch first
Failure msg
// return the "wrapped" inner function
Parser innerFn
/// Run a parser with some input
let run parser input =
// unwrap parser to get inner function
let (Parser innerFn) = parser
// call inner function with input
innerFn input
fsi
的编译输出:
$ fsi
F# Interactive for F# 4.1
Freely distributed under the Apache 2.0 Open Source License
For help type #help;;
> #load "Temp.fsx";;
[Loading /Users/asaf/programming/PCfs/Temp.fsx]
namespace FSI_0002
module Temp = begin
type Result<'a> =
| Success of 'a
| Failure of string
type Parser<'T> = | Parser of (string -> Result<'T * string>)
val pchar : charToMatch:char -> Parser<char>
val run : parser:Parser<'a> -> input:string -> Result<'a * string>
end
我还没有在 .fsx 文件中测试它本身,但我认为它应该可以工作。您可以将其放入 .fs 文件中,比方说 File1.fs 并在顶部放置一个模块声明,然后执行 #load "File1.fs"
然后在 FSI 中你可以将 xxy 引用为 File1.xxy;;
,你可以将其创建为 File1.B "jds";;
.
module File1
type A =
| B of string
| C of int
let xxy = B "sds"
通常你只需将代码从编辑器直接发送到 FSI 并在编辑器中工作,这样你就不会遇到这个问题...
例如
根据你的类型我得到:
File1.Failure "blah";;
val it : File1.Result<'a> = Failure "blah"
编辑 fsx 文件示例:
以下是我的评论中提到的一些变体。文件名为 Script11.fsx
,模块名称为 Temp
(指定时)。它刚刚加载到 PowerShell 中的 fsi 会话 运行:#load @"Script11.fsx";;
1) 没有模块名称声明。带有文件名的前缀。
open System
type A =
| B of string
| C of int
let xxy = B "sds"
//> Script11.xxy;;
//val it : Script11.A = B "sds"
//>
2) 模块名称声明。没有缩进。带有模块名称的前缀。
module Temp
open System
type A =
| B of string
| C of int
let xxy = B "sds"
//> Temp.xxy;;
//val it : Temp.A = B "sds"
//>
3) 缩进的模块名称(您的版本),带有 等号,这会将模块放在文件名 space 中。您可以看到它以 module Temp = begin
开头。带有文件名和模块名的前缀。
module Temp =
open System
type A =
| B of string
| C of int
let xxy = B "sds"
//> Script11.Temp.xxy;;
//val it : Script11.Temp.A = B "sds"
//>
4) Autoopen与否的区别:
//[<AutoOpen>]
module Temp =
open System
type A =
| B of string
| C of int
let xxy = B "sds"
如果您注释掉 Autoopen
,您将需要通过在模块名称前加上前缀来引用模块的内容。
open Script11;;
Temp.xxy;;
//val it : Temp.A = B "sds"
如果你使用Autopen
那么你仍然需要打开文件名但是你可以直接访问你模块里面的东西。
> open Script11;;
> xxy;;
//val it : A = B "sds"
长话短说,如果你有顶级声明,通常你不需要Autoopen,如果你不缩进和创建额外的名字space你可以直接访问内容.否则你正在创建一个本地模块,显然你必须使用路径。参见 Modules。
当您在 F# 交互中 #load
一个 .fsx
文件时,该文件中的所有定义最终都在以该文件命名的模块中,大写。因此,例如,如果您 #load "pc.fsx"
,那么您所有的定义都将在名为 Pc
.
的模块中结束
#load "pc.fsx"
let r = Pc.Success "value"
只需在 fsx
的顶部声明一个具有相同名称的 AutoOpen
模块,就可以了:
[<AutoOpen>]
module Temp
open System
/// Type that represents Success/Failure in parsing
type Result<'a> =
| Success of 'a
| Failure of string
/// Type that wraps a parsing function
type Parser<'T> = Parser of (string -> Result<'T * string>)
/// Parse a single character
let pchar charToMatch =
// define a nested inner function
let innerFn str =
if String.IsNullOrEmpty(str) then
Failure "No more input"
else
let first = str.[0]
if first = charToMatch then
let remaining = str.[1..]
Success (charToMatch,remaining)
else
let msg = sprintf "Expecting '%c'. Got '%c'" charToMatch first
Failure msg
// return the "wrapped" inner function
Parser innerFn
/// Run a parser with some input
let run parser input =
// unwrap parser to get inner function
let (Parser innerFn) = parser
// call inner function with input
innerFn input
在 fsi 中加载:
» fsharpi
F# Interactive for F# 4.1
Freely distributed under the Apache 2.0 Open Source License
For help type #help;;
> #load "Temp.fsx";;
[Loading /Users/kostas/workspace/fsharp/Temp.fsx]
namespace FSI_0002
type Result<'a> =
| Success of 'a
| Failure of string
type Parser<'T> = | Parser of (string -> Result<'T * string>)
val pchar : charToMatch:char -> Parser<char>
val run : parser:Parser<'a> -> input:string -> Result<'a * string>
> run (pchar 'f') "foo";;
val it : Result<char * string> = Success ('f', "oo")
> Failure "42";;
val it : Result<'a> = Failure "42"
>
我通过 brew install mono
在 OS X 上安装了单声道,当我在终端中 运行 fsharpi
时加载了 F# v.4.01。
我有一个 .fsx
文件,其中定义了一些类型和函数。我希望在 fsi
(fsharpi
的别名)中交互使用它们。为此,我启动了 fsi
和 运行 #load "pc.fsx;;"
- 文件被加载和编译,我看到了通用命名空间下的所有类型定义和函数类型。出于某种原因,REPL 无法识别自定义类型(因此我无法使用类型构造函数)和函数,因此我收到错误 FS0039:The value or constructor '<insert type or function name>' is not defined
。我该如何克服这个问题?
编辑:
该文件名为 Temp.fsx
,内容包含在名为 Temp
.
文件内容:
module Temp =
open System
/// Type that represents Success/Failure in parsing
type Result<'a> =
| Success of 'a
| Failure of string
/// Type that wraps a parsing function
type Parser<'T> = Parser of (string -> Result<'T * string>)
/// Parse a single character
let pchar charToMatch =
// define a nested inner function
let innerFn str =
if String.IsNullOrEmpty(str) then
Failure "No more input"
else
let first = str.[0]
if first = charToMatch then
let remaining = str.[1..]
Success (charToMatch,remaining)
else
let msg = sprintf "Expecting '%c'. Got '%c'" charToMatch first
Failure msg
// return the "wrapped" inner function
Parser innerFn
/// Run a parser with some input
let run parser input =
// unwrap parser to get inner function
let (Parser innerFn) = parser
// call inner function with input
innerFn input
fsi
的编译输出:
$ fsi
F# Interactive for F# 4.1
Freely distributed under the Apache 2.0 Open Source License
For help type #help;;
> #load "Temp.fsx";;
[Loading /Users/asaf/programming/PCfs/Temp.fsx]
namespace FSI_0002
module Temp = begin
type Result<'a> =
| Success of 'a
| Failure of string
type Parser<'T> = | Parser of (string -> Result<'T * string>)
val pchar : charToMatch:char -> Parser<char>
val run : parser:Parser<'a> -> input:string -> Result<'a * string>
end
我还没有在 .fsx 文件中测试它本身,但我认为它应该可以工作。您可以将其放入 .fs 文件中,比方说 File1.fs 并在顶部放置一个模块声明,然后执行 #load "File1.fs"
然后在 FSI 中你可以将 xxy 引用为 File1.xxy;;
,你可以将其创建为 File1.B "jds";;
.
module File1
type A =
| B of string
| C of int
let xxy = B "sds"
通常你只需将代码从编辑器直接发送到 FSI 并在编辑器中工作,这样你就不会遇到这个问题...
例如
根据你的类型我得到:
File1.Failure "blah";;
val it : File1.Result<'a> = Failure "blah"
编辑 fsx 文件示例:
以下是我的评论中提到的一些变体。文件名为 Script11.fsx
,模块名称为 Temp
(指定时)。它刚刚加载到 PowerShell 中的 fsi 会话 运行:#load @"Script11.fsx";;
1) 没有模块名称声明。带有文件名的前缀。
open System
type A =
| B of string
| C of int
let xxy = B "sds"
//> Script11.xxy;;
//val it : Script11.A = B "sds"
//>
2) 模块名称声明。没有缩进。带有模块名称的前缀。
module Temp
open System
type A =
| B of string
| C of int
let xxy = B "sds"
//> Temp.xxy;;
//val it : Temp.A = B "sds"
//>
3) 缩进的模块名称(您的版本),带有 等号,这会将模块放在文件名 space 中。您可以看到它以 module Temp = begin
开头。带有文件名和模块名的前缀。
module Temp =
open System
type A =
| B of string
| C of int
let xxy = B "sds"
//> Script11.Temp.xxy;;
//val it : Script11.Temp.A = B "sds"
//>
4) Autoopen与否的区别:
//[<AutoOpen>]
module Temp =
open System
type A =
| B of string
| C of int
let xxy = B "sds"
如果您注释掉 Autoopen
,您将需要通过在模块名称前加上前缀来引用模块的内容。
open Script11;;
Temp.xxy;;
//val it : Temp.A = B "sds"
如果你使用Autopen
那么你仍然需要打开文件名但是你可以直接访问你模块里面的东西。
> open Script11;;
> xxy;;
//val it : A = B "sds"
长话短说,如果你有顶级声明,通常你不需要Autoopen,如果你不缩进和创建额外的名字space你可以直接访问内容.否则你正在创建一个本地模块,显然你必须使用路径。参见 Modules。
当您在 F# 交互中 #load
一个 .fsx
文件时,该文件中的所有定义最终都在以该文件命名的模块中,大写。因此,例如,如果您 #load "pc.fsx"
,那么您所有的定义都将在名为 Pc
.
#load "pc.fsx"
let r = Pc.Success "value"
只需在 fsx
的顶部声明一个具有相同名称的 AutoOpen
模块,就可以了:
[<AutoOpen>]
module Temp
open System
/// Type that represents Success/Failure in parsing
type Result<'a> =
| Success of 'a
| Failure of string
/// Type that wraps a parsing function
type Parser<'T> = Parser of (string -> Result<'T * string>)
/// Parse a single character
let pchar charToMatch =
// define a nested inner function
let innerFn str =
if String.IsNullOrEmpty(str) then
Failure "No more input"
else
let first = str.[0]
if first = charToMatch then
let remaining = str.[1..]
Success (charToMatch,remaining)
else
let msg = sprintf "Expecting '%c'. Got '%c'" charToMatch first
Failure msg
// return the "wrapped" inner function
Parser innerFn
/// Run a parser with some input
let run parser input =
// unwrap parser to get inner function
let (Parser innerFn) = parser
// call inner function with input
innerFn input
在 fsi 中加载:
» fsharpi
F# Interactive for F# 4.1
Freely distributed under the Apache 2.0 Open Source License
For help type #help;;
> #load "Temp.fsx";;
[Loading /Users/kostas/workspace/fsharp/Temp.fsx]
namespace FSI_0002
type Result<'a> =
| Success of 'a
| Failure of string
type Parser<'T> = | Parser of (string -> Result<'T * string>)
val pchar : charToMatch:char -> Parser<char>
val run : parser:Parser<'a> -> input:string -> Result<'a * string>
> run (pchar 'f') "foo";;
val it : Result<char * string> = Success ('f', "oo")
> Failure "42";;
val it : Result<'a> = Failure "42"
>