Closed5

.NET CLIのF# Interactiveで遊ぼう

四ツ山伊吹四ツ山伊吹

方針

  • 定義済みのあれやこれやを何でも評価してみる。

F# Interactive

Microsoft (R) F# Interactive version 12.0.1.0 for F# 6.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;
四ツ山伊吹四ツ山伊吹

Basic Types in Microsoft.FSharp.Core Namespace

.NETクラスライブラリのSystem.Objectオブジェクト、およびSystem.ValueTypeクラスの派生

https://github.com/dotnet/fsharp/blob/main/src/fsharp/FSharp.Core/prim-types-prelude.fs#L8-L31

...
// これらはMicrosoft.FSharp.Core 名前空間に属する
> Microsoft.FSharp.Core.obj  
- obj;; // 同じ
val it: unit -> obj

// C#のコンストラクターを呼び出すような感じで利用できる
> obj ();;
val it: obj = System.Object

// ふつう、Microsoft.FSharp.Core.Operators moduleに属す同名の識別子が
// 優先して参照されるためここでは完全修飾名で指定(以下同様)
> Microsoft.FSharp.Core.float32;;
val it: unit -> float32

// そのデータ型の既定値とリテラルを得るのに便利(?)
> Microsoft.FSharp.Core.float32 ();;
val it: float32 = 0.0f

> Microsoft.FSharp.Core.float;;     
val it: unit -> float

> Microsoft.FSharp.Core.float ();;
val it: float = 0.0

// Microsoft.FSharp.Core.float32 の別名
> Microsoft.FSharp.Core.single;;  
val it: unit -> single

> Microsoft.FSharp.Core.single ();;
val it: single = 0.0f

// Microsoft.FSharp.Core.float の別名
> Microsoft.FSharp.Core.double;;   
val it: unit -> double

> Microsoft.FSharp.Core.double ();;
val it: double = 0.0

> Microsoft.FSharp.Core.sbyte;;    
val it: unit -> sbyte

> Microsoft.FSharp.Core.sbyte ();;
val it: sbyte = 0y

> Microsoft.FSharp.Core.byte;;    
val it: unit -> byte

> Microsoft.FSharp.Core.byte ();;
val it: byte = 0uy

> Microsoft.FSharp.Core.int8;;   
val it: unit -> int8

> Microsoft.FSharp.Core.int8 ();;
val it: int8 = 0y

> Microsoft.FSharp.Core.uint8;;  
val it: unit -> uint8

> Microsoft.FSharp.Core.uint8 ();;
val it: uint8 = 0uy

> Microsoft.FSharp.Core.int16;;   
val it: unit -> int16

> Microsoft.FSharp.Core.int16 ();;
val it: int16 = 0s

> Microsoft.FSharp.Core.uint16;;  
val it: unit -> uint16

> Microsoft.FSharp.Core.uint16 ();;
val it: uint16 = 0us

> Microsoft.FSharp.Core.int32;;    
val it: unit -> int32

> Microsoft.FSharp.Core.int32 ();; 
val it: int32 = 0

> Microsoft.FSharp.Core.uint32;;  
val it: unit -> uint32

> Microsoft.FSharp.Core.uint32 ();;
val it: uint32 = 0u

> Microsoft.FSharp.Core.int64;;    
val it: unit -> int64

> Microsoft.FSharp.Core.int64 ();;
val it: int64 = 0L

> Microsoft.FSharp.Core.uint64;;  
val it: unit -> uint64

> Microsoft.FSharp.Core.uint64 ();;
val it: uint64 = 0UL

> Microsoft.FSharp.Core.char;;  
val it: unit -> char

> Microsoft.FSharp.Core.char ();;
val it: char = '\000'

> Microsoft.FSharp.Core.bool
- bool;; // 同じ
val it: unit -> bool

> bool ();;           
val it: bool = false

> Microsoft.FSharp.Core.int;;                                   
val it: unit -> int

> Microsoft.FSharp.Core.int ();;
val it: int = 0

> Microsoft.FSharp.Core.uint;;     
val it: unit -> uint

> Microsoft.FSharp.Core.uint ();;
val it: uint = 0u

取り扱いがちょっと普通でないやつ

...
> Microsoft.FSharp.Core.exn  
- exn;; // 同じ
val it: arg00: string -> exn

// System.Exception オブジェクトが返ってくる
> exn "exception";;
val it: exn = System.Exception: exception {Data = dict [];
                                           HResult = -2146233088;
                                           HelpLink = null;
                                           InnerException = null;
                                           Message = "exception";
                                           Source = null;
                                           StackTrace = null;
                                           TargetSite = null;}
       
> exn ();;
val it: exn =
  System.Exception: Exception of type 'System.Exception' was thrown.
    {Data = dict [];
     HResult = -2146233088;
     HelpLink = null;
     InnerException = null;
     Message = "Exception of type 'System.Exception' was thrown.";
     Source = null;
     StackTrace = null;
     TargetSite = null;}

// オーバーロードを解決できないデータ型たち
> Microsoft.FSharp.Core.string;;

  Microsoft.FSharp.Core.string;;
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

stdin(1,1): error FS0041: A unique overload for method 'String' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a0

Candidates:
 - System.String(value: System.ReadOnlySpan<char>) : string
 - System.String(value: char[]) : string
 - System.String(value: nativeptr<char>) : string
 - System.String(value: nativeptr<sbyte>) : string

> Microsoft.FSharp.Core.string [||];;
val it: string = ""

> Microsoft.FSharp.Core.decimal;;

  Microsoft.FSharp.Core.decimal;;
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

stdin(1,1): error FS0041: A unique overload for method 'Decimal' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a0

Candidates:
 - System.Decimal(bits: System.ReadOnlySpan<int>) : decimal
 - System.Decimal(bits: int[]) : decimal
 - System.Decimal(value: float) : decimal
 - System.Decimal(value: float32) : decimal
 - System.Decimal(value: int) : decimal
 - System.Decimal(value: int64) : decimal
 - System.Decimal(value: uint32) : decimal
 - System.Decimal(value: uint64) : decimal
 
 > Microsoft.FSharp.Core.decimal (Microsoft.FSharp.Core.int ());;
val it: decimal = 0M

> Microsoft.FSharp.Core.nativeint;;

  Microsoft.FSharp.Core.nativeint;;
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

stdin(1,1): error FS0041: A unique overload for method 'IntPtr' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a0

Candidates:
 - System.IntPtr(value: int) : nativeint
 - System.IntPtr(value: int64) : nativeint
 - System.IntPtr(value: voidptr) : nativeint
 
> Microsoft.FSharp.Core.nativeint (Microsoft.FSharp.Core.int ());;
val it: nativeint = 0n

> Microsoft.FSharp.Core.unativeint;;                              

  Microsoft.FSharp.Core.unativeint;;
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

/stdin(17,1): error FS0041: A unique overload for method 'UIntPtr' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a0

Candidates:
 - System.UIntPtr(value: uint32) : unativeint
 - System.UIntPtr(value: uint64) : unativeint
 - System.UIntPtr(value: voidptr) : unativeint
 
 > Microsoft.FSharp.Core.unativeint (Microsoft.FSharp.Core.uint ());;
val it: unativeint = 0un

補遺

...
// 'null'はキーワード
> null;;
val it: 'a when 'a: null

// タブキーの入力補完にはあらわれるのに参照できないやつ
> Microsoft.FSharp.Core.unit;;

  Microsoft.FSharp.Core.unit;;
  -----------------^^^^

stdin(1,1): error FS0039: The value, constructor, namespace or type 'Core' is not defined.
四ツ山伊吹四ツ山伊吹

Basic Operators in Microsoft.FSharp.Core.Operators module

基本

  • ふつう修飾名なしで利用する。
  • 数値型っぽいのはC#でいうキャスト式のように振る舞う関数。
    • あるいはint.Parse()メソッドのような変換を担うとでもいうべき関数。
  • Microsoft.FSharp.Core.Operators.stringはC#でいうToString()メソッドのように振る舞う関数。
    • パイプライン演算子でこれに入れれば何でもstringにしてくれる。
> int;;
val it: (int -> int) = <fun:it@1>

> float;;
val it: (int -> float) = <fun:it@2-1>

> byte;;
val it: (int -> byte) = <fun:it@3-2>

> decimal;;
val it: (int -> decimal) = <fun:it@4-3>

> string;;
val it: ('a -> string)

いわゆる“演算子”

  • よく知られているように、F#では記号的な演算子も式。
> (=);;
val it: ('a -> 'a -> bool) when 'a: equality

> (|>);;
val it: ('a -> ('a -> 'b) -> 'b)

> (>>);;
val it: (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c)

// 何か警告された
> (^);;

  (^);;
  -^

stdin(1,2): warning FS0062: This construct is for ML compatibility. Consider using the '+' operator instead. This may require a type annotation to indicate it acts on strings. This message can be disabled using '--nowarn:62' or '#nowarn "62"'.

val it: (string -> string -> string) = <fun:it@1>

標準ストリーム (std*)

  • 標準ストリームをあらわす演算子としてstdinstdoutstderrが用意されている。
  • これらは.NETのSystem.Consoleクラスに規定されるプロパティの別名・略称であり、次のように対応している。
F# .NETのプロパティ
stdin System.Console.In System.IO.TextReader
stdout System.Console.Out System.IO.TextWriter
stderr System.Console.Error System.IO.TextWriter
> stdin;;
val it: System.IO.TextReader =
  System.IO.SyncTextReader {KeyAvailable = false;}

> stdout;;
val it: System.IO.TextWriter =
  System.IO.TextWriter+SyncTextWriter
    {Encoding = System.Text.UTF8Encoding+UTF8EncodingSealed;
     FormatProvider = ;
     NewLine = "
";}

> stderr;;
val it: System.IO.TextWriter =
  System.IO.TextWriter+SyncTextWriter
    {Encoding = System.Text.UTF8Encoding+UTF8EncodingSealed;
     FormatProvider = ;
     NewLine = "
";}

// データ型がSystem.IO.TextReaderであることを利用して
// stdinに.NETのメンバーを“生やす”ことができる
> stdin.ReadLine;;
val it: (unit -> string) = <fun:it@1>

// stdoutについても同様
> stdout.FormatProvider;;
val it: System.IFormatProvider =
   {Calendar = System.Globalization.GregorianCalendar;
    CompareInfo = CompareInfo - ;
    CultureTypes = SpecificCultures;
    DateTimeFormat = System.Globalization.DateTimeFormatInfo;
    DisplayName = "Invariant Language (Invariant Country)";
    EnglishName = "Invariant Language (Invariant Country)";
    IetfLanguageTag = "";
    IsNeutralCulture = false;
    IsReadOnly = true;
    KeyboardLayoutId = 127;
    LCID = 127;
    Name = "";
    NativeName = "Invariant Language (Invariant Country)";
    NumberFormat = System.Globalization.NumberFormatInfo;
    OptionalCalendars = [|System.Globalization.GregorianCalendar|];
    Parent = ;
    TextInfo = TextInfo - ;
    ThreeLetterISOLanguageName = "ivl";
    ThreeLetterWindowsLanguageName = "IVL";
    TwoLetterISOLanguageName = "iv";
    UseUserOverride = false;}
四ツ山伊吹四ツ山伊吹

Simple Constant Expressions

Numeric Literals

...
// int (int32)
> (000_000_106, -59l, -0o22, -0x12);;
val it: int * int * int * int = (106, -59, -18, -18)

// float (double)
> (122., 0b0000_0011_0001LF, 17.0, 114E+84);;
val it: float * float * float * float =
  (122.0, 2.420921665e-322, 17.0, 1.14e+86)

// decimal
> (0m, 107.109M, 901_1_30421923_2136m, 423_7_0_21.85151_72392M);;
val it: decimal * decimal * decimal * decimal =
  (0M, 107.109M, 9011304219232136M, 4237021.8515172392M)

// sbyte
> (-0x47y, -0O55y, 0b0011000y, 0019y);;
val it: sbyte * sbyte * sbyte * sbyte = (-71y, -45y, 24y, 19y)

// byte
> (51uy, 0b1111_1111uy, 88uy, 0X0063uy);; 
val it: byte * byte * byte * byte = (51uy, 255uy, 88uy, 99uy)

Strings and Characters

...
> "abc\
- def";;
val it: string = "abcdef"

> @"abc\                  
- def";;
val it: string = "abc\
def"

> @"\\ ""F#"" //";; 
val it: string = "\\ "F#" //"

> "\u20ac";;    
val it: string = "€"

> "\U0001d782";;
val it: string = "𝞂"

> 'q'B;;
val it: byte = 113uy

> "jL2t"B;;
val it: byte[] = [|106uy; 76uy; 50uy; 116uy|]

> @"c:\documents\files\u0066.txt"B;;
val it: byte[] =
  [|99uy; 58uy; 92uy; 100uy; 111uy; 99uy; 117uy; 109uy; 101uy; 110uy; 116uy;
    115uy; 92uy; 102uy; 105uy; 108uy; 101uy; 115uy; 92uy; 117uy; 48uy; 48uy;
    54uy; 54uy; 46uy; 116uy; 120uy; 116uy|]
    
 """<?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTD- s/PropertyList-1.0.dtd">
- <plist version="1.0">
- <array>
-     <string>\\</string>
-     <string>a</string>
- </array>
- </plist>
- """;;
val it: string =
  "<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <string>\\</string>
    <string>a</string>
</array>
</plist>
"
四ツ山伊吹四ツ山伊吹

Identifier Replacements

> __LINE__;;
val it: string = "11"

> __SOURCE_FILE__;;
val it: string = "stdin"

> __SOURCE_DIRECTORY__;;
val it: string = "/Users/███████"
このスクラップは2023/08/11にクローズされました