I have this JavaScript file (Rhino 1.7R4).
importPackage(java.io);
importPackage(java.lang);
importPackage(java.util);
var reader = new BufferedReader( new InputStreamReader(System['in']) );
var line = reader.readLine();
var tok = new java.util.StringTokenizer(line);
var A = Integer.parseInt(tok.nextToken());
var B = Integer.parseInt(tok.nextToken());
var C = Integer.parseInt(tok.nextToken());
// System.out.printf( "A=%d, B=%d, C=%d\n", A, B, C );
System.out.printf( "A=%f, B=%f, C=%f\n", A, B, C );
When I uncomment first printf - I'm getting
A=Exception in thread "main" org.mozilla.javascript.WrappedException: Wrapped java.util.IllegalFormatConversionException: d != java.lang.Double
at org.mozilla.javascript.Context.throwAsScriptRuntimeEx(Context.java:1754)
at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:148)
at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:225)
at org.mozilla.javascript.optimizer.OptRuntime.callN(OptRuntime.java:52)
at test._c_script_0(Unknown Source)
at test.call(Unknown Source)
at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394)
at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3091)
at test.call(Unknown Source)
at test.exec(Unknown Source)
at org.mozilla.javascript.optimizer.OptRuntime$1.run(OptRuntime.java:218)
at org.mozilla.javascript.Context.call(Context.java:489)
at org.mozilla.javascript.ContextFactory.call(ContextFactory.java:504)
at org.mozilla.javascript.optimizer.OptRuntime.main(OptRuntime.java:206)
at test.main(Unknown Source)
Caused by: java.util.IllegalFormatConversionException: d != java.lang.Double
at java.util.Formatter$FormatSpecifier.failConversion(Unknown Source)
at java.util.Formatter$FormatSpecifier.printInteger(Unknown Source)
at java.util.Formatter$FormatSpecifier.print(Unknown Source)
at java.util.Formatter.format(Unknown Source)
at java.io.PrintStream.format(Unknown Source)
at java.io.PrintStream.printf(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:126)
... 13 more
That's a reault of the JavaScript type system. All numbers in JavaScript are doubles, so while `Integer.parseInt("4.5") returns 4, it needs to be converted to 4.0 for JavaScript.
Fortunately, 64-bit doubles have enough precision to represent any 32-bit int exactly, so on the JavaScript side you typically don't need to worry about it. But the Java object behind the value is always a Double and gets converted automatically when it needs to be. But since System.out.printf takes arguments of type Object it has to be passed as is.
Related
I am trying to use DotCover in FAKE , but it is throwing some error , as I am new to FAKE as well as F# , it's becoming difficult for me to understand the root cause of the problem . Here is the code :
#r "D:/FAKEProject/Fake/packages/FAKE/tools/FakeLib.dll"
open Fake
open Fake.DotCover
let testDir = "D:/FAKEProject/Fake/test/"
let filters = ""
Target "Clean" (fun _ ->
CleanDirs [testDir]
)
Target "TestCoverage" (fun _ ->
!! ("D:/FAKEProject/Fake/UnitTest/UnitTest.dll")
|> DotCoverNUnit
(fun p -> { p with Output = testDir ## "NUnitDotCover.snapshot"
ToolPath = "D:/tools/dotCover/dotCover.exe"
Filters = filters })
(fun nunitOptions -> nunitOptions)
)
"Clean"
==> "TestCoverage"
RunTargetOrDefault "TestCoverage"`
It is giving this error
System.Exception: Error running D:/tools/dotCover/dotCover.exe with exitcode -1
at Fake.DotCover.buildParamsAndExecute#124-6.Invoke(String message) in C:\code\fake\src\app\FakeLib\DotCover.fs:line 124
at Fake.DotCover.buildParamsAndExecute[a](a parameters, FSharpFunc`2 buildArguments, String toolPath, String workingDir, Boolean failBuild) in C:\code\fake\src\app\FakeLib\DotCover.fs:line 124
at Fake.DotCover.DotCoverNUnit(FSharpFunc`2 setDotCoverParams, FSharpFunc`2 setNUnitParams, IEnumerable`1 assemblies) in C:\code\fake\src\app\FakeLib\DotCover.fs:line 190
at FSI_0005.DotCover.clo#16-2.Invoke(Unit _arg2) in D:\FAKEProject\Fake\DotCover.fsx:line 17
at Fake.TargetHelper.runSingleTarget(TargetTemplate`1 target) in C:\code\fake\src\app\FakeLib\TargetHelper.fs:line 492`
I am not able to understand why it is searching in C:\code\fake\src\app\fakelib\dotcover.fs
and what is dotcover.fs it is looking for
How to solve this problem , as I am stuck at this error , If anyone can help me regarding this , it would be very helpful .
Thank You
The mysterious C:\code\fake\src\app\FakeLib\DotCover.fs line is simply telling you the filename (and line number) of the source file that threw the error. Not the filename on your system, but the filename on the system where your FAKE.exe file was built. In other words, it's just telling you where the exception was thrown from.
Looking at the FAKE source code, I see that line 124 is near the end of the following block of code:
let buildParamsAndExecute parameters buildArguments toolPath workingDir failBuild =
let args = buildArguments parameters
trace (toolPath + " " + args)
let result = ExecProcess (fun info ->
info.FileName <- toolPath
info.WorkingDirectory <- getWorkingDir workingDir
info.Arguments <- args) TimeSpan.MaxValue
let ExitCodeForFailedTests = -3
if (result = ExitCodeForFailedTests && not failBuild) then
trace (sprintf "DotCover %s exited with errorcode %d" toolPath result)
else if (result = ExitCodeForFailedTests && failBuild) then
failwithf "Failing tests, use ErrorLevel.DontFailBuild to ignore failing tests. Exited %s with errorcode %d" toolPath result
else if (result <> 0) then
failwithf "Error running %s with exitcode %d" toolPath result
else
trace (sprintf "DotCover exited successfully")
The failwithf function is F#'s equivalent of "throw new Exception()", but it lets you specify a message (using printfn-style format codes like %s) to go with the exception. So there's nothing mysterious going on here in F#, it's just that your D:/tools/dotCover/dotCover.exe program has returned a -1 return code. Return codes of -1 usually mean "generic error", so that's not much help in figuring out the cause.
Your next troubleshooting step is to run your dotCover.exe program manually, giving it the same arguments that FAKE is giving it (shouldn't be too hard to figure out, since the FAKE option records are usually pretty well-named) and the same input. Then see what error messages, if any, dotCover.exe is printing out before it fails.
In my previous question Kurt pointed me to this code of FsCheck about setting the Arbitrary type.
I have the following Arbitrary (disclaimer: I have no idea what I am doing..., still finding FsCheck notoriously hard to understand but I'm dead set on getting it to work), which in itself is a simplified version of something I created earlier:
type MyArb() =
inherit Arbitrary<DoNotSize<int64>>()
override x.Generator = Arb.Default.DoNotSizeInt64().Generator
And I use it as instructed:
[<Property(Verbose = true, Arbitrary= [| typeof<MyArb> |])>]
static member MultiplyIdentity (x: int64) = x * 1L = x
This gives me a (somewhat hopeful) error message that I'm missing something:
System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
----> System.Exception : No instances found on type Tests.Arithmetic.MyArb. Check that the type is public and has public static members with the right signature.
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at FsCheck.Runner.checkMethod(Config config, MethodInfo m, FSharpOption`1 target) in C:\Users\Kurt\Projects\FsCheck\FsCheck\src\FsCheck\Runner.fs:line 318
at FsCheck.NUnit.Addin.FsCheckTestMethod.runTestMethod(TestResult testResult) in C:\Users\Kurt\Projects\FsCheck\FsCheck\src\FsCheck.NUnit.Addin\FsCheckTestMethod.fs:line 100
Looking back at that Github code I see two Atrbitrary classes but neither with any inheritance and they both have different static members.
How can I create a random-number generator and assign it as an Arbitrary statically to my NUnit tests?
The type you provide in the Property.Arbitrary parameter should have static members (possibly several) of type Arb. As in the code you linked:
type TestArbitrary2 =
static member NegativeDouble() =
Arb.Default.Float()
|> Arb.mapFilter (abs >> ((-) 0.0)) (fun t -> t <= 0.0)
Applying this to your code, it should look like this:
type MyArb() =
static member m() = Arb.Default.DoNotSizeInt64()
The meaning of the Property.Arbitrary parameter is not "an implementation of Arbitrary", but rather "a bucket of typeclass implementations".
You see, the original Haskell implementation of QuickCheck relies on typeclasses to provide values of different types. In order for a particular type to be "quick-checkable", there needs to be an instance of the 'Arbitrary' class defined for that type (for example, here are instances for all basic types).
Since F# doesn't support type classes as such, FsCheck has to fake it, and this is the scheme used there: each type class instance is represented by a static member that returns the function table. For example, if we wanted to simulate the Eq typeclass, we'd define it something like this:
type Eq<'a> = { eq: 'a -> 'a -> bool; neq: 'a -> 'a -> bool }
type EqInstances() =
static member ForInt() : Eq<int> =
{ eq = (=); neq = (<>) }
static member ForMyCustomType() : Eq<MyCustomType> =
{ eq = fun a b -> a.CompareTo(b) = 0
neq = fun a b -> a.CompareTo(b) <> 0 }
But because you can't just scan all static member in all loaded assemblies (that would be prohibitively expensive), there is this little inconvenience of providing the type explicitly (as a bonus, it allows to control the visibility of "instances").
This question demonstrates clearly, IMO, why the Reflection-based API for FsCheck is less than ideal. I tend to avoid that API completely, so I'd instead write the OP property like this:
open FsCheck
open FsCheck.Xunit
[<Property>]
let MultiplyIdentity () =
Arb.Default.DoNotSizeInt64 () |> Prop.forAll <| fun (DoNotSize x) -> x * 1L = x
As the open directives suggest, this uses FsCheck.Xunit instead of FsCheck.NUnit, but AFAIK, there's no difference in the way the API works.
The advantage of this approach is that it's type-safe and more lightweight, because you don't have to implement static classes every time you need to tweak FsCheck.
If you prefer the approach described by Mark Seemann, then you may also consider using plain-FsCheck and get rid of FsCheck.Xunit entirely:
module Tests
open FsCheck
let [<Xunit.Fact>] ``Multiply Identity (passing)`` () =
Arb.Default.DoNotSizeInt64 ()
|> Prop.forAll
<| fun (DoNotSize x) ->
x * 1L = x
|> Check.QuickThrowOnFailure
let [<Xunit.Fact>] ``Multiply Identity (failing)`` () =
Arb.Default.DoNotSizeInt64 ()
|> Prop.forAll
<| fun (DoNotSize x) ->
x * 1L = -1L |# sprintf "(%A should equal %A)" (x * 1L) x
|> Check.QuickThrowOnFailure
xUnit.net testrunner output:
------ Test started: Assembly: Library1.dll ------
Test 'Tests.Multiply Identity (failing)' failed: System.Exception:
Falsifiable, after 1 test (2 shrinks) (StdGen (2100552947,296238694)):
Label of failing property: (0L should equal 0L)
Original:
DoNotSize -23143L
Shrunk:
DoNotSize 0L
at <StartupCode$FsCheck>.$Runner.get_throwingRunner#365-1.Invoke(String me..
at <StartupCode$FsCheck>.$Runner.get_throwingRunner#355.FsCheck-IRunner-On..
at FsCheck.Runner.check[a](Config config, a p)
at FsCheck.Check.QuickThrowOnFailure[Testable](Testable property)
C:\Users\Nikos\Desktop\Library1\Library1\Library1.fs(15,0): at Tests.Multi..
1 passed, 1 failed, 0 skipped, took 0.82 seconds (xUnit.net 2.1.0 build 3179).
I've been trying to write a JSON deserialiser for a while now, but haven't been able to find my error. Why is Newtonsoft telling me, Unexpected token when deserializing object: StartObject, after deserialising this?
type ThisFails =
{ a : string * string
m : Map<string, string> }
type ThisWorks =
{ y : Map<string, string>
z : string * string }
testCase "failing test - array before object" <| fun _ ->
let res = deserialise<ThisFails> Serialisation.converters
"""{"a":["xyz","zyx"],"m":{}}"""
Assert.Equal("should be eq to res", { a = "xyz", "zyx"; m = Map.empty }, res)
testCase "passing test - array after object" <| fun _ ->
let res = deserialise<ThisWorks> Serialisation.converters
"""{"y":{},"z":["xyz","zyx"]}"""
Assert.Equal("should be eq to res", { y = Map.empty; z = "xyz", "zyx" }, res)
The subject is the TupleArrayConverter.
The trace of that converter is:
reading json [Newtonsoft.Json.FSharp.TupleArrayConverter]
type => System.Tuple`2[System.String,System.String]
value token, pre-deserialise [Newtonsoft.Json.FSharp.TupleArrayConverter]
path => "a[0]"
token_type => String
value token, post-deserialise [Newtonsoft.Json.FSharp.TupleArrayConverter]
path => "a[1]"
token_type => String
value token, pre-deserialise [Newtonsoft.Json.FSharp.TupleArrayConverter]
path => "a[1]"
token_type => String
value token, post-deserialise [Newtonsoft.Json.FSharp.TupleArrayConverter]
path => "a"
token_type => EndArray
after EndArray token, returning [Newtonsoft.Json.FSharp.TupleArrayConverter]
path => "m"
token_type => PropertyName
In the converter, I'm consuming the last token, the end array, as you can see in the terminating case:
match reader.TokenType with
| JsonToken.EndArray ->
read JsonToken.EndArray |> req |> ignore
acc
And I'm consuming the StartArray token in the beginning...
So: why isn't this code working? (Newtonsoft.Json 6.0.8)
This is the error:
map tests/failing test - array before object: Exception: Newtonsoft.Json.JsonSerializationException: Unexpected token when deserializing object: StartObject. Path 'm', line 1, position 24.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolvePropertyAndCreatorValues (Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, Newtonsoft.Json.JsonReader reader, System.Type objectType, IDictionary`2& extensionData) [0x00000] in <filename unknown>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, Newtonsoft.Json.Serialization.ObjectConstructor`1 creator, System.String id) [0x00000] in <filename unknown>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract objectContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, Newtonsoft.Json.Serialization.JsonProperty containerProperty, System.String id, System.Boolean& createdFromNonDefaultCreator) [0x00000] in <filename unknown>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x00000] in <filename unknown>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x00000] in <filename unknown>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, Boolean checkAdditionalContent) [0x00000] in <filename unknown>:0 (00:00:00.1500996)
1 tests run: 0 passed, 0 ignored, 0 failed, 1 errored (00:00:00.2482623)
Been debugging your code together with JSON.Net.
It turns out that after you consumed the EndArray token in your failing case the reader then points to a PropertyName token, that is all good.
Then after your converter has completed execution JSON.Net executes this.
} while (!exit && reader.Read());
Read() then moves the reader to the next token which in your failing case is StartObject causing the deserializer to fail.
So, I am not an expert at JSON.Net but thinking about providing a provider for a string value in JSON.Net I probably wouldn't advance the reader after conversion meaning the reader still points to the string value. Along the same line of thinking it makes sense when consuming an array to leave the reader at last token of the array value ie the EndArray token.
So my suggestion is merely this:
match reader.TokenType with
| JsonToken.EndArray ->
// read JsonToken.EndArray |> req |> ignore
Logger.debug logger <| fun _ ->
LogLine.sprintf
[ "path", reader.Path |> box
"token_type", reader.TokenType |> box ]
"after EndArray token, returning"
acc
This makes my test program:
[<EntryPoint>]
let main argv =
let works = deserialize<ThisWorks> """{"y":{},"z":["xyz","zyx"]}"""
printfn "%A" works
let fails = deserialize<ThisFails> """{"a":["xyz","zyx"],"m":{}}"""
printfn "%A" fails
0
Print
{y = map [];
z = ("xyz", "zyx");}
{a = ("xyz", "zyx");
m = map [];}
Hopefully this helps you resolve this error (you might already have done so)
I wrote the following code to execute a SQLServer StoredProc in F#
module SqlUtility =
open System
open System.Data
open System.Data.SqlClient
SqlUtility.GetSqlConnection "MyDB"
|> Option.bind (fun con -> SqlUtility.GetSqlCommand "dbo.usp_MyStordProc" con)
|> Option.bind (fun cmd ->
let param1 = new SqlParameter("#User", SqlDbType.NVarChar, 50)
param1.Value <- user
cmd.Parameters.Add(param1) |> ignore
let param2 = new SqlParameter("#PolicyName", SqlDbType.NVarChar, 10)
param2.Value <- policyName
cmd.Parameters.Add(param2) |> ignore
Some(cmd)
)
|> Option.bind (fun cmd -> SqlUtility.ExecuteReader cmd)
|> Option.bind (fun rdr -> ExtractValue rdr)
let GetSqlConnection (conName : string) =
let conStr = ConfigHandler.GetConnectionString conName
try
let con = new SqlConnection(conStr)
con.Open()
Some(con)
with
| :? System.Exception as ex -> printfn "Failed to connect to DB %s with Error %s " conName ex.Message; None
| _ -> printfn "Failed to connect to DB %s" conName; None
let GetSqlCommand (spName : string) (con : SqlConnection) =
let cmd = new SqlCommand()
cmd.Connection <- con
cmd.CommandText <- spName
cmd.CommandType <- CommandType.StoredProcedure
Some(cmd)
let AddParameters (cmd : SqlCommand) (paramList : SqlParameter list) =
paramList |> List.iter (fun p -> cmd.Parameters.Add p |> ignore)
let ExecuteReader (cmd : SqlCommand ) =
try
Some(cmd.ExecuteReader())
with
| :? System.Exception as ex -> printfn "Failed to execute reader with error %s" ex.Message; None
I have multiple problems with this code
First and foremost the repeated use of Option.bind is very irritating... and is adding noise. I need a more clearer way to check if the output was None and if not then proceed.
At the end there should be a cleanupfunction where I should be able to close + dispose the reader, command and connection. But currently at the end of the pipeline all I have is the reader.
The function which is adding parameters... it looks like it is modifying the "state" of the command parameter because the return type is still the same command which was sent it... with some added state. I wonder how a more experienced functional programmer would have done this.
Visual Studio gives me a warning at each of the place where i do exception handling. what's wrong with that" it says
This type test or downcast will always hold
The way I want this code to look is this
let x : MyRecord seq = GetConnection "con" |> GetCommand "cmd" |> AddParameter "#name" SqlDbType.NVarchar 50 |> AddParameter "#policyname" SqlDbType.NVarchar 50 |> ExecuteReader |> FunctionToReadAndGenerateSeq |> CleanEverything
Can you recommend how can I take my code to the desired level and also any other improvement?
I think that using options to represent failed computations is more suitable to purely functional langauges. In F#, it is perfectly fine to use exceptions to denote that a computation has failed.
Your code simply turns exceptions into None values, but it does not really handle this situation - this is left to the caller of your code (who will need to decide what to do with None). You may as well just let them handle the exception. If you want to add more information to the exception, you can define your own exception type and throw that instead of leaving the standard exceptions.
The following defines a new exception type and a simple function to throw it:
exception SqlUtilException of string
// This supports the 'printf' formatting style
let raiseSql fmt =
Printf.kprintf (SqlUtilException >> raise) fmt
Using plain .NET style with a few simplifications using F# features, the code looks a lot simpler:
// Using 'use' the 'Dispose' method is called automatically
let connName = ConfigHandler.GetConnectionString "MyDB"
use conn = new SqlConnection(connName)
// Handle exceptions that happen when opening the connection
try conn.Open()
with ex -> raiseSql "Failed to connect to DB %s with Error %s " connName ex.Message
// Using object initializer, we can nicely set the properties
use cmd =
new SqlCommand( Connection = conn, CommandText = "dbo.usp_MyStordProc",
CommandType = CommandType.StoredProcedure )
// Add parameters
// (BTW: I do not think you need to set the type - this will be infered)
let param1 = new SqlParameter("#User", SqlDbType.NVarChar, 50, Value = user)
let param2 = new SqlParameter("#PolicyName", SqlDbType.NVarChar, 10, Value = policyName)
cmd.Parameters.AddRange [| param1; param2 |]
use reader =
try cmd.ExecuteReader()
with ex -> raiseSql "Failed to execute reader with error %s" ex.Message
// Do more with the reader
()
It looks more like .NET code, but that is perfectly fine. Dealing with databases in F# is going to use imperative style and trying to hide that will only make the code confusing. Now, there is a number of other neat F# features you could use - especially the support for dynamic operators ?, which would give you something like:
let connName = ConfigHandler.GetConnectionString "MyDB"
// A wrapper that provides dynamic access to database
use db = new DynamicDatabase(connName)
// You can call stored procedures using method call syntax
// and pass SQL parameters as standard arguments
let rows = db.Query?usp_MyStordProc(user, policy)
// You can access columns using the '?' syntax again
[ for row in rows -> row?Column1, row?Column2 ]
For more information about this, see the following MSDN series:
How to: Dynamically Invoke a Stored Procedure
Step 1: Create a Database and Show the Poll Options
Step 2: Implement Voting for an Option
Could someone please show me why the function below expects integer[] instead of byte[]
type Node =
| InternalNode of int*Node*Node
| LeafNode of int * byte
let weight node =
match node with
|InternalNode(w,_,_) -> w
|LeafNode(w,_)-> w
let createNodes inputValues =
let getCounts (leafNodes:(int*byte)[])=
inputValues |>Array.iter
(fun b-> let (w,v) =leafNodes.[(int)b]
leafNodes.[(int)b]<-(w+1,v))
leafNodes
[|for b in 0uy..255uy -> (0 ,b)|] |>getCounts
|>List.ofArray
|>List.map LeafNode
The only place that tells the F# compiler something about the type of the parameter is inside the lambda function given to Array.iter (from the use of this higher-order function, the compiler infers that you're working with arrays). Inside the lambda function you have:
leafNodes.[(int)b]
As a side-note, int in this code is just a normal F# function (not a special type cast construct), so the usual way to write it would be just:
leafNodes.[int b]
Now, the compiler knows that b (that is, values of the array given as the argument) can be converted to integer, however the int function works with other types (you can write for example int 3.13f. In ambiguous cases like this, the compiler uses int as the default type, so that's the reason why you're seeing a type int[].
You can add type annotations to the declaration like this (and it will work without any other changes, because byte can be converted to integer using the int function):
let createNodes (inputValues:byte[]) =
// ...