diff --git a/.markdownlint.json b/.markdownlint.json
new file mode 100644
index 0000000..f2a375a
--- /dev/null
+++ b/.markdownlint.json
@@ -0,0 +1,3 @@
+{
+ "MD024": false
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c14f63..c1f1bf4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,12 +9,10 @@
## [5.0.0-alpha.21.1](https://github.com/fable-compiler/Fable.Python/compare/v5.0.0-alpha.21.0...v5.0.0-alpha.21.1) (2025-12-18)
-
### Features
* Add Json static class with Fable-aware serialization ([#175](https://github.com/fable-compiler/Fable.Python/issues/175)) ([1eb5005](https://github.com/fable-compiler/Fable.Python/commit/1eb500523c6d6f43247bc3510a6045ec8d9d9d4e))
-
### Bug Fixes
* correct manifest to last released version ([bb9cb88](https://github.com/fable-compiler/Fable.Python/commit/bb9cb881c00b7ea6809ad3a87a35a7ebc0ff9008))
@@ -23,7 +21,6 @@
## [5.0.0-alpha.21.0](https://github.com/fable-compiler/Fable.Python/compare/v5.0.0-alpha.21...v5.0.0-alpha.21.0) (2025-12-16)
-
### Features
* Add exception types ([#173](https://github.com/fable-compiler/Fable.Python/issues/173)) ([72f09b2](https://github.com/fable-compiler/Fable.Python/commit/72f09b2ff6e208e3ab057430a355814611abd46c))
@@ -33,7 +30,6 @@
* Fable v5 ([#147](https://github.com/fable-compiler/Fable.Python/issues/147)) ([abf8e6a](https://github.com/fable-compiler/Fable.Python/commit/abf8e6a1f7bbc2eae152431d04d6b8b5675f7795))
* FastAPI async handlers ([#174](https://github.com/fable-compiler/Fable.Python/issues/174)) ([26cec1f](https://github.com/fable-compiler/Fable.Python/commit/26cec1f239f9244a7c1da1d00bbf1a479596bb3c))
-
### Bug Fixes
* add missing models.py for pydantic example and update README ([#168](https://github.com/fable-compiler/Fable.Python/issues/168)) ([b76ce98](https://github.com/fable-compiler/Fable.Python/commit/b76ce989e0598d0007a8a1be9addfea97936eae7))
@@ -43,35 +39,30 @@
* use plain int/string types for open ([b202a25](https://github.com/fable-compiler/Fable.Python/commit/b202a25bd7f48538fadc50125294a9252714d364))
* use string types for open ([f211f8b](https://github.com/fable-compiler/Fable.Python/commit/f211f8bb9445dd6930926fe48aab6a69720dd30f))
-
### Miscellaneous Chores
* sync with Fable 5.0.0-alpha.21 ([fd2685c](https://github.com/fable-compiler/Fable.Python/commit/fd2685c2f992c2d8058ac1bc1261d647271359df))
## [5.0.0-alpha.20.2](https://github.com/fable-compiler/Fable.Python/compare/v5.0.0-alpha.20.1...v5.0.0-alpha.20.2) (2025-12-09)
-
### Features
* add Python stdlib bindings for logging, random, and expand string module ([#166](https://github.com/fable-compiler/Fable.Python/issues/166)) ([709d6c2](https://github.com/fable-compiler/Fable.Python/commit/709d6c2b29199965926ff639727fdcc1bb2e1fb8))
## [5.0.0-alpha.20.1](https://github.com/fable-compiler/Fable.Python/compare/v5.0.0-alpha.20...v5.0.0-alpha.20.1) (2025-12-08)
-
### Bug Fixes
* relax FSharp.Core dependency to >= 5.0.0 ([#163](https://github.com/fable-compiler/Fable.Python/issues/163)) ([10eb65b](https://github.com/fable-compiler/Fable.Python/commit/10eb65b22a157078e1b66bd8fb202b0cd2acbedc))
## [5.0.0-alpha.20](https://github.com/fable-compiler/Fable.Python/compare/v5.0.0-alpha.20...v5.0.0-alpha.20) (2025-12-08)
-
### Features
* add write ([334e800](https://github.com/fable-compiler/Fable.Python/commit/334e80089c081bda25633f83dae037fc6c8fe6f5))
* Added bindings for Pydantic and FastAPI + examples ([#151](https://github.com/fable-compiler/Fable.Python/issues/151)) ([826629e](https://github.com/fable-compiler/Fable.Python/commit/826629e465fca15d444a4ca37b851b8aab488f9a))
* Fable v5 ([#147](https://github.com/fable-compiler/Fable.Python/issues/147)) ([abf8e6a](https://github.com/fable-compiler/Fable.Python/commit/abf8e6a1f7bbc2eae152431d04d6b8b5675f7795))
-
### Bug Fixes
* handle return type correctly ([a634168](https://github.com/fable-compiler/Fable.Python/commit/a6341684ac8bb3f1b244f448c22e1fe6f208fbc0))
diff --git a/release-please-config.json b/release-please-config.json
index aa93e33..255646e 100644
--- a/release-please-config.json
+++ b/release-please-config.json
@@ -3,7 +3,7 @@
"packages": {
".": {
"release-type": "simple",
- "release-as": "5.0.0-alpha.21.2",
+ "release-as": "5.0.0-alpha.21.3",
"include-component-in-tag": false,
"include-v-in-tag": true,
"changelog-path": "CHANGELOG.md"
diff --git a/src/Fable.Python.fsproj b/src/Fable.Python.fsproj
index b524b01..42effae 100644
--- a/src/Fable.Python.fsproj
+++ b/src/Fable.Python.fsproj
@@ -36,6 +36,8 @@
+
+
diff --git a/src/fable/Types.fs b/src/fable/Types.fs
new file mode 100644
index 0000000..267ae23
--- /dev/null
+++ b/src/fable/Types.fs
@@ -0,0 +1,55 @@
+/// Utilities for detecting and working with Fable types at runtime in Python.
+/// These helpers are useful when you need to distinguish between native Python types
+/// and Fable-compiled F# types (e.g., Int32, Float64, FSharpArray).
+module Fable.Python.Fable.Types
+
+open Fable.Core
+
+/// Get the Python type name of an object
+[]
+let typeName (o: obj) : string = nativeOnly
+
+/// Check if an object is a Fable integral type (Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64)
+let isIntegralType (o: obj) : bool =
+ match typeName o with
+ | "Int8"
+ | "Int16"
+ | "Int32"
+ | "Int64"
+ | "UInt8"
+ | "UInt16"
+ | "UInt32"
+ | "UInt64" -> true
+ | _ -> false
+
+/// Check if an object is a Fable numeric type (integral types + Float32, Float64)
+let isNumericType (o: obj) : bool =
+ match typeName o with
+ | "Int8"
+ | "Int16"
+ | "Int32"
+ | "Int64"
+ | "UInt8"
+ | "UInt16"
+ | "UInt32"
+ | "UInt64"
+ | "Float32"
+ | "Float64" -> true
+ | _ -> false
+
+/// Check if an object is a Fable array type (FSharpArray, GenericArray, or typed arrays)
+let isArrayType (o: obj) : bool =
+ match typeName o with
+ | "FSharpArray"
+ | "GenericArray"
+ | "Int8Array"
+ | "Int16Array"
+ | "Int32Array"
+ | "Int64Array"
+ | "UInt8Array"
+ | "UInt16Array"
+ | "UInt32Array"
+ | "UInt64Array"
+ | "Float32Array"
+ | "Float64Array" -> true
+ | _ -> false
diff --git a/src/fastapi/FastAPI.fs b/src/fastapi/FastAPI.fs
index f3060f5..c49e457 100644
--- a/src/fastapi/FastAPI.fs
+++ b/src/fastapi/FastAPI.fs
@@ -136,33 +136,27 @@ type RouterWebSocketAttribute(path: string) =
/// JSON response class
[]
-type JSONResponse(content: obj, ?status_code: int) =
- class end
+type JSONResponse(content: obj, ?status_code: int) = class end
/// HTML response class
[]
-type HTMLResponse(content: string, ?status_code: int) =
- class end
+type HTMLResponse(content: string, ?status_code: int) = class end
/// Plain text response class
[]
-type PlainTextResponse(content: string, ?status_code: int) =
- class end
+type PlainTextResponse(content: string, ?status_code: int) = class end
/// Redirect response class
[]
-type RedirectResponse(url: string, ?status_code: int) =
- class end
+type RedirectResponse(url: string, ?status_code: int) = class end
/// Streaming response class
[]
-type StreamingResponse(content: obj, ?media_type: string) =
- class end
+type StreamingResponse(content: obj, ?media_type: string) = class end
/// File response class
[]
-type FileResponse(path: string, ?filename: string, ?media_type: string) =
- class end
+type FileResponse(path: string, ?filename: string, ?media_type: string) = class end
// ============================================================================
// Request and WebSocket
@@ -256,8 +250,7 @@ type WebSocket() =
/// HTTP exception for returning error responses
[]
-type HTTPException(status_code: int, ?detail: string) =
- class end
+type HTTPException(status_code: int, ?detail: string) = class end
// ============================================================================
// Dependency Injection
@@ -422,7 +415,7 @@ type UploadFile() =
/// File parameter marker
[]
[]
-let File() : UploadFile = nativeOnly
+let File () : UploadFile = nativeOnly
/// Form parameter marker
[]
@@ -452,7 +445,10 @@ type APIRouter(?prefix: string, ?tags: ResizeArray) =
/// Include another router with prefix and tags
[]
- member _.include_router_with_prefix_and_tags(_router: APIRouter, _prefix: string, _tags: ResizeArray) : unit = nativeOnly
+ member _.include_router_with_prefix_and_tags
+ (_router: APIRouter, _prefix: string, _tags: ResizeArray)
+ : unit =
+ nativeOnly
// ============================================================================
// FastAPI Application
@@ -471,7 +467,10 @@ type FastAPI(?title: string, ?description: string, ?version: string) =
/// Include a router with prefix and tags
[]
- member _.include_router_with_prefix_and_tags(_router: APIRouter, _prefix: string, _tags: ResizeArray) : unit = nativeOnly
+ member _.include_router_with_prefix_and_tags
+ (_router: APIRouter, _prefix: string, _tags: ResizeArray)
+ : unit =
+ nativeOnly
/// Add middleware
[]
@@ -571,8 +570,7 @@ type OAuth2PasswordRequestForm() =
/// HTTP Basic authentication
[]
-type HTTPBasic() =
- class end
+type HTTPBasic() = class end
/// HTTP Basic credentials
[]
@@ -587,8 +585,7 @@ type HTTPBasicCredentials() =
/// HTTP Bearer authentication
[]
-type HTTPBearer() =
- class end
+type HTTPBearer() = class end
/// HTTP Bearer credentials (token in Authorization header)
[]
@@ -603,18 +600,15 @@ type HTTPAuthorizationCredentials() =
/// API Key in header
[]
-type APIKeyHeader(name: string) =
- class end
+type APIKeyHeader(name: string) = class end
/// API Key in query parameter
[]
-type APIKeyQuery(name: string) =
- class end
+type APIKeyQuery(name: string) = class end
/// API Key in cookie
[]
-type APIKeyCookie(name: string) =
- class end
+type APIKeyCookie(name: string) = class end
// ============================================================================
// CORS Middleware
@@ -622,8 +616,7 @@ type APIKeyCookie(name: string) =
/// CORS middleware for handling Cross-Origin Resource Sharing
[]
-type CORSMiddleware =
- class end
+type CORSMiddleware = class end
/// CORS middleware configuration helper
module CORSMiddleware =
@@ -634,7 +627,15 @@ module CORSMiddleware =
/// Add CORS middleware to app with all origins allowed
[]
- let addToApp (_app: FastAPI) (_middleware: obj) (_origins: string array) (_credentials: bool) (_methods: string array) (_headers: string array) : unit = nativeOnly
+ let addToApp
+ (_app: FastAPI)
+ (_middleware: obj)
+ (_origins: string array)
+ (_credentials: bool)
+ (_methods: string array)
+ (_headers: string array)
+ : unit =
+ nativeOnly
// ============================================================================
// Encoders
diff --git a/src/flask/Flask.fs b/src/flask/Flask.fs
index f07348f..d1ee175 100644
--- a/src/flask/Flask.fs
+++ b/src/flask/Flask.fs
@@ -259,8 +259,7 @@ let make_response_with_status (_body: obj) (_status: int) : Response = nativeOnl
/// Flask Blueprint for modular applications
[]
-type Blueprint(name: string, import_name: string, ?url_prefix: string) =
- class end
+type Blueprint(name: string, import_name: string, ?url_prefix: string) = class end
// ============================================================================
// Flask Application
diff --git a/src/pydantic/Pydantic.fs b/src/pydantic/Pydantic.fs
index 8b95cda..0f0be90 100644
--- a/src/pydantic/Pydantic.fs
+++ b/src/pydantic/Pydantic.fs
@@ -458,4 +458,3 @@ type Base64Str = string
/// JSON type - validates JSON string and parses it
[]
type JsonValue = obj
-
diff --git a/src/stdlib/Json.fs b/src/stdlib/Json.fs
index d87043d..4172e7d 100644
--- a/src/stdlib/Json.fs
+++ b/src/stdlib/Json.fs
@@ -15,24 +15,28 @@ type IExports =
/// Serialize obj to a JSON formatted string with indentation
/// See https://docs.python.org/3/library/json.html#json.dumps
abstract dumps: obj: obj * indent: int -> string
+
/// Serialize obj to a JSON formatted string with a custom default function
/// See https://docs.python.org/3/library/json.html#json.dumps
[]
abstract dumps: obj: obj * ``default``: (obj -> obj) -> string
+
/// Serialize obj to a JSON formatted string with indentation and custom default
/// See https://docs.python.org/3/library/json.html#json.dumps
[]
abstract dumps: obj: obj * indent: int * ``default``: (obj -> obj) -> string
+
/// Serialize obj to a JSON formatted string with separators, ensure_ascii, and custom default
/// See https://docs.python.org/3/library/json.html#json.dumps
[]
- abstract dumps:
- obj: obj * separators: string array * ensure_ascii: bool * ``default``: (obj -> obj) -> string
+ abstract dumps: obj: obj * separators: string array * ensure_ascii: bool * ``default``: (obj -> obj) -> string
+
/// Serialize obj to a JSON formatted string with indent, separators, ensure_ascii, and custom default
/// See https://docs.python.org/3/library/json.html#json.dumps
[]
abstract dumps:
obj: obj * indent: int * separators: string array * ensure_ascii: bool * ``default``: (obj -> obj) -> string
+
/// Deserialize a JSON document from a string to a Python object
/// See https://docs.python.org/3/library/json.html#json.loads
abstract loads: s: string -> obj
@@ -42,14 +46,17 @@ type IExports =
/// Serialize obj as a JSON formatted stream with indentation
/// See https://docs.python.org/3/library/json.html#json.dump
abstract dump: obj: obj * fp: TextIOWrapper * indent: int -> unit
+
/// Serialize obj as a JSON formatted stream with a custom default function
/// See https://docs.python.org/3/library/json.html#json.dump
[]
abstract dump: obj: obj * fp: TextIOWrapper * ``default``: (obj -> obj) -> unit
+
/// Serialize obj as a JSON formatted stream with indentation and custom default
/// See https://docs.python.org/3/library/json.html#json.dump
[]
abstract dump: obj: obj * fp: TextIOWrapper * indent: int * ``default``: (obj -> obj) -> unit
+
/// Deserialize a JSON document from a file-like object to a Python object
/// See https://docs.python.org/3/library/json.html#json.load
abstract load: fp: TextIOWrapper -> obj
@@ -127,7 +134,13 @@ let fableDefault (o: obj) : obj =
if hasattr o "tag" && hasattr o "fields" then
let cases = getCases o
let tag: int = getattr o "tag" :?> int
- let caseName = if tag < cases.Length then cases.[tag] else "Case" + string tag
+
+ let caseName =
+ if tag < cases.Length then
+ cases.[tag]
+ else
+ "Case" + string tag
+
unionToList o caseName
elif hasattr o "__slots__" then
slotsToDict o
@@ -152,7 +165,13 @@ type Json =
/// Serialize obj to JSON with indentation, custom separators, and ensure_ascii, automatically handling Fable types
static member inline dumps(obj: obj, indent: int, separators: string array, ensureAscii: bool) : string =
- json.dumps (obj, indent = indent, separators = separators, ensure_ascii = ensureAscii, ``default`` = fableDefault)
+ json.dumps (
+ obj,
+ indent = indent,
+ separators = separators,
+ ensure_ascii = ensureAscii,
+ ``default`` = fableDefault
+ )
/// Serialize obj as JSON stream to file, automatically handling Fable types
static member inline dump(obj: obj, fp: TextIOWrapper) : unit =
@@ -163,9 +182,7 @@ type Json =
json.dump (obj, fp, indent, ``default`` = fableDefault)
/// Deserialize a JSON document from a string to a Python object
- static member inline loads(s: string) : obj =
- json.loads s
+ static member inline loads(s: string) : obj = json.loads s
/// Deserialize a JSON document from a file-like object to a Python object
- static member inline load(fp: TextIOWrapper) : obj =
- json.load fp
+ static member inline load(fp: TextIOWrapper) : obj = json.load fp
diff --git a/src/stdlib/Logging.fs b/src/stdlib/Logging.fs
index 5dde395..8523e68 100644
--- a/src/stdlib/Logging.fs
+++ b/src/stdlib/Logging.fs
@@ -70,27 +70,35 @@ type Logger(name: string, ?level: int) =
member _.critical(msg: string) : unit = nativeOnly
/// Log a message with severity ERROR and exception info
member _.``exception``(msg: string) : unit = nativeOnly
+
/// Log a message with the specified level
[]
member _.log(level: int, msg: string) : unit = nativeOnly
+
/// Set the logging level
[]
member _.setLevel(level: int) : unit = nativeOnly
+
/// Get the effective logging level
[]
member _.getEffectiveLevel() : int = nativeOnly
+
/// Check if the logger is enabled for the specified level
[]
member _.isEnabledFor(level: int) : bool = nativeOnly
+
/// Add the specified handler to this logger
[]
member _.addHandler(handler: Handler) : unit = nativeOnly
+
/// Remove the specified handler from this logger
[]
member _.removeHandler(handler: Handler) : unit = nativeOnly
+
/// Check if this logger has any handlers configured
[]
member _.hasHandlers() : bool = nativeOnly
+
/// The name of the logger
member _.name: string = nativeOnly
@@ -114,6 +122,7 @@ type IExports =
/// Return a logger with the specified name
[]
abstract getLogger: name: string -> Logger
+
/// Return the root logger
[]
abstract getLogger: unit -> Logger
diff --git a/src/stdlib/Random.fs b/src/stdlib/Random.fs
index ae92219..9eb989a 100644
--- a/src/stdlib/Random.fs
+++ b/src/stdlib/Random.fs
@@ -12,6 +12,7 @@ type IExports =
/// See https://docs.python.org/3/library/random.html#random.seed
[]
abstract seed: a: int -> unit
+
/// Initialize the random number generator
/// See https://docs.python.org/3/library/random.html#random.seed
abstract seed: a: nativeint -> unit
@@ -58,10 +59,12 @@ type IExports =
/// See https://docs.python.org/3/library/random.html#random.choice
[]
abstract choice: seq: 'T[] -> 'T
+
/// Return a random element from the non-empty sequence
/// See https://docs.python.org/3/library/random.html#random.choice
[]
abstract choice: seq: 'T list -> 'T
+
/// Return a random element from the non-empty sequence
/// See https://docs.python.org/3/library/random.html#random.choice
abstract choice: seq: ResizeArray<'T> -> 'T
@@ -70,10 +73,12 @@ type IExports =
/// See https://docs.python.org/3/library/random.html#random.sample
[]
abstract sample: population: 'T[] * k: int -> ResizeArray<'T>
+
/// Return a k length list of unique elements chosen from the population sequence
/// See https://docs.python.org/3/library/random.html#random.sample
[]
abstract sample: population: 'T list * k: int -> ResizeArray<'T>
+
/// Return a k length list of unique elements chosen from the population sequence
/// See https://docs.python.org/3/library/random.html#random.sample
[]
@@ -83,10 +88,12 @@ type IExports =
/// See https://docs.python.org/3/library/random.html#random.choices
[]
abstract choices: population: 'T[] * k: int -> ResizeArray<'T>
+
/// Return a k sized list of elements chosen from the population with replacement
/// See https://docs.python.org/3/library/random.html#random.choices
[]
abstract choices: population: 'T list * k: int -> ResizeArray<'T>
+
/// Return a k sized list of elements chosen from the population with replacement
/// See https://docs.python.org/3/library/random.html#random.choices
[]
diff --git a/src/stdlib/Sys.fs b/src/stdlib/Sys.fs
index 317e5b4..fe84be6 100644
--- a/src/stdlib/Sys.fs
+++ b/src/stdlib/Sys.fs
@@ -60,10 +60,12 @@ type IExports =
/// Exits with code 0, indicating success
/// See https://docs.python.org/3/library/sys.html#sys.exit
abstract exit: unit -> 'a
+
/// Exits with provided status
/// See https://docs.python.org/3/library/sys.html#sys.exit
[]
abstract exit: status: int -> 'a
+
/// Exits with provided status
/// See https://docs.python.org/3/library/sys.html#sys.exit
abstract exit: status: nativeint -> 'a
diff --git a/src/stdlib/asyncio/Futures.fs b/src/stdlib/asyncio/Futures.fs
index dcc1700..54dc034 100644
--- a/src/stdlib/asyncio/Futures.fs
+++ b/src/stdlib/asyncio/Futures.fs
@@ -3,9 +3,7 @@ namespace Fable.Python.AsyncIO
open Fable.Core
-type Awaitable<'T> =
- interface
- end
+type Awaitable<'T> = interface end
type Future<'T> =
inherit Awaitable<'T>
diff --git a/test/Fable.Python.Test.fsproj b/test/Fable.Python.Test.fsproj
index 50dc0bd..6292242 100644
--- a/test/Fable.Python.Test.fsproj
+++ b/test/Fable.Python.Test.fsproj
@@ -25,6 +25,7 @@
+
diff --git a/test/TestTypes.fs b/test/TestTypes.fs
new file mode 100644
index 0000000..66743c8
--- /dev/null
+++ b/test/TestTypes.fs
@@ -0,0 +1,132 @@
+module Fable.Python.Tests.Types
+
+open Util.Testing
+open Fable.Python.Fable.Types
+
+// Test typeName function
+
+[]
+let ``test typeName returns Int32 for int`` () =
+ let value = 42
+ typeName value |> equal "Int32"
+
+[]
+let ``test typeName returns Int64 for int64`` () =
+ let value = 42L
+ typeName value |> equal "Int64"
+
+[]
+let ``test typeName returns Float64 for float`` () =
+ let value = 3.14
+ typeName value |> equal "Float64"
+
+[]
+let ``test typeName returns str for string`` () =
+ let value = "hello"
+ typeName value |> equal "str"
+
+// Test isIntegralType function
+
+[]
+let ``test isIntegralType returns true for int`` () =
+ let value = 42
+ isIntegralType value |> equal true
+
+[]
+let ``test isIntegralType returns true for int64`` () =
+ let value = 42L
+ isIntegralType value |> equal true
+
+[]
+let ``test isIntegralType returns true for int16`` () =
+ let value = 42s
+ isIntegralType value |> equal true
+
+[]
+let ``test isIntegralType returns true for int8`` () =
+ let value = 42y
+ isIntegralType value |> equal true
+
+[]
+let ``test isIntegralType returns true for uint32`` () =
+ let value = 42u
+ isIntegralType value |> equal true
+
+[]
+let ``test isIntegralType returns true for uint64`` () =
+ let value = 42UL
+ isIntegralType value |> equal true
+
+[]
+let ``test isIntegralType returns false for float`` () =
+ let value = 3.14
+ isIntegralType value |> equal false
+
+[]
+let ``test isIntegralType returns false for string`` () =
+ let value = "hello"
+ isIntegralType value |> equal false
+
+// Test isNumericType function
+
+[]
+let ``test isNumericType returns true for int`` () =
+ let value = 42
+ isNumericType value |> equal true
+
+[]
+let ``test isNumericType returns true for int64`` () =
+ let value = 42L
+ isNumericType value |> equal true
+
+[]
+let ``test isNumericType returns true for float`` () =
+ let value = 3.14
+ isNumericType value |> equal true
+
+[]
+let ``test isNumericType returns true for float32`` () =
+ let value = 3.14f
+ isNumericType value |> equal true
+
+[]
+let ``test isNumericType returns false for string`` () =
+ let value = "hello"
+ isNumericType value |> equal false
+
+[]
+let ``test isNumericType returns false for bool`` () =
+ let value = true
+ isNumericType value |> equal false
+
+// Test isArrayType function
+
+[]
+let ``test isArrayType returns true for int array`` () =
+ let value = [| 1; 2; 3 |]
+ isArrayType value |> equal true
+
+[]
+let ``test isArrayType returns true for string array`` () =
+ let value = [| "a"; "b"; "c" |]
+ isArrayType value |> equal true
+
+[]
+let ``test isArrayType returns true for float array`` () =
+ let value = [| 1.0; 2.0; 3.0 |]
+ isArrayType value |> equal true
+
+[]
+let ``test isArrayType returns false for list`` () =
+ let value = [ 1; 2; 3 ]
+ isArrayType value |> equal false
+
+[]
+let ``test isArrayType returns false for string`` () =
+ let value = "hello"
+ isArrayType value |> equal false
+
+[]
+let ``test isArrayType returns false for int`` () =
+ let value = 42
+ isArrayType value |> equal false