So, i'am learning OCaml step by step and i've recently met the great world of "module langage" in OCaml.
Here is my problem:
module type TEST = sig
val addend : 'a -> list
end
module Test : TEST =
struct
let addend (val,lol) =
val::lol
end
when i try to use this inside the interpretor it tells me that i have a syntax error ...
I know that's this kind of anoying question asked by this guy who's a noob and thinks stack overflow is here to rewrite is poorly optimised code but still, after hours spend searching for a solution i've almost gived up at this point...
OCaml is cool, but why is it so hard.
First, in the definition of the type of your module : you have to specify the type of element of your list. You cannot use list alone.
The following code will compile :
module type TEST = sig
val addend : 'a -> 'a list
end;;
But will not do what you want as you want to define later a function that takes a element, a list and puts this element in this list.
So the signature of such function is :
'a -> 'a list -> 'a list
So the type of your module shall be :
module type TEST = sig
val addend : 'a -> 'a list -> 'a list
end;;
And the implementation :
module Test : TEST =
struct
let addend a l = a::l
end
;;
Please note that in your code, you may be influenced by C like language where you pass the arguments in parenthesis. In Ocaml, parenthesis are used for tuples ; this means that your implementation was different from the signature.
You get a syntax error becaue val is a keyword. You cannot use it as an identifier.
Related
https://tryfsharp.fsbolero.io/
printfn "Hello"
works as expected without errors, however, using pipe operator
"Hello" |> printfn
The type 'string' is not compatible with the type 'Printf.TextWriterFormat'
I understood the pipe operator behavior:
f(a) is equivalent to a |> f
Why does the latter generate the error?? Thanks.
Yes. The pipe operator does what you think it does. However, printfn is "special" that it takes a kind of "formattable string" (there are different kinds of these) and the compiler does its magic only when the format string appears as a direct argument.
In other words, your "Hello" in the first example is not really a string, it is a Printf.TextWriterFormat object, magically created by the compiler.
Still, you can do what you want by using an explict format string. This approach you'll see quite a bit in real-world code:
"Hello" |> printfn "%s"
Here, %s means: give me a string. The magic of F# in this case again takes the format string, here "%s", this time with an argument of type string, and turns it into a function.
Note 1: that this "surprise effect" is being considered and the community works towards adding a printn function (i.e., without the f which stands for format) to just take a simple string: https://github.com/fsharp/fslang-suggestions/issues/1092
Note 2: if you do want to pass arguments to printfn around, you can make the type explicit, but this is done very rarely:
let x = Printf.TextWriterFormat<unit> "Hello"
x |> printfn // now it's legal
Note 3: you might wonder why the compiler doesn't apply its magic to the lh-side of |> as well. The reason is that |> is not an intrinsic to the compiler, but just another overridable operator. Fixing this is therefor technically very hard (there can be any amount of operators on the lh-side), though it has been considered at certain times.
Other alternative
In the comments, the OP suggested that he/she/they didn't like the idea of having to use printfn "%i" and the like, and ended up writing print, printInt etc functions.
If you go that route, you can write your code in a class with only static methods, while using function-style naming. Then just open the static type (this is a new feature in F# 6).
module MyPrinters =
// create a static type (no constructors)
type Printers =
static member print x = printfn "%s" x // string
static member print x = printfn "%i" x // integer
static member print x = printfn "%M" x // decimal
static member print x = printfn "%f" x // float
module X =
// open the static type
open type MyPrinters.Printers
let f() = print 42
let g() = print "test"
I have a large (>8 elements) object that contains a potentially empty list of strings ids.
I'd like to read the data in and parse in elm. Initially my attempts returned <internal structure> or undefined.
I found the problem to be not handling nulls. It took me a long time to diagnose and testing each of the elements is tedious. I don't know where to look for compiler or run time hints. How does one approach this in elm?
Are there established ways to quickly validate an Elm model against a javascript object? Are there good places to put Debug.* statements? Ways to test with the repl?
The Object
# curl '0.0.0.0:3003/person_search_view?select=ids'|jq -c
[{"ids":["11488"]},{"ids":["11489"]},{"ids":[null]}]
The code
-- testing what part is failing
-- *tedious* made a function to test reading in each type [List String, String, Int]
justID : (List String) -> Person
justID ids =
Person 0 "" "" "" "" "" "" 0 "" 0 0 0 ids [""] [""] ""
stringlist : Decode.Decoder (List String)
stringlist = list (oneOf [string, null "N/A"] )
memberDecoderID : Decode.Decoder Person
memberDecoderID =
Decode.succeed
justID
|: ("ids" := stringlist ) -- here was failing (List string)
fetchAllUrl = "http://0.0.0.0:3003/person_search_view?order=curage"
fetchAll : Effects Action
fetchAll =
Http.get (Decode.list memberDecoderID ) fetchAllUrl
|> Task.toResult
|> Task.map FetchAllDone
|> Effects.task
I would recommend building unit tests for your custom decoders. Not only that, but I would recommend starting with unit tests when building any decoders. If you start building unit tests around the smallest decoders possible using JSON values appropriate to what you'd see in the real world, you will probably catch errors much faster, and you'll be guaranteed to future-proof your code because each error you've caught along the way will have to be fixed via a backwards-compatible unit test.
For example, you could use the entertainingly-named deadfoxygrandpa/elm-test library and write tests like the following:
-- in your CustomDecoders.elm file...
stringlist : Decode.Decoder (List String)
stringlist = list (oneOf [string, null "N/A"] )
-- in your CustomDecoders-Tests.elm file...
tests : Test
tests =
suite "A Test Suite"
[ test "stringlist decodes string lists"
<| assertEqual (decodeString stringlist "[\"1\",\"2\",\"3\"]") (Ok ["1","2","3"])
, test "stringlist decodes null"
<| assertEqual (decodeString stringlist "[null]") (Ok ["N/A"])
]
You still may have to deal with cryptic JSON parsing error messages, but now you'll have a much easier time finding the problem since you'll know exactly which tests fail.
It is my first day of learning F#. I am going through tryfsharp.org when I came across following example for topic Functions as Values
let chrisTest test =
test "Chris"
let isMe x =
if x = "Chris" then
"it is Chris!"
else
"it's someone else"
chrisTest isMe
Explanation on the site:-
chrisTest is a simple higher order function that executes a test against a string value. The isMe function checks to see if a string is equal to "Chris". Passing isChris to chrisTest passes the string "Chris" as an argument to the `isChris" function, and returns the result of "it is Chris!".
My thought:- Value of isMe function is passed to function chrisTest in the last line of program. However what I do not get is there is no value passed to isMe function. How does isMe function decide to execute what value to return?
For this case we can start by replacing everything in christest. Then you have
chrisTest isMe = isme "Chris" (as test=isme)
and then the rest follows by a similar procedure
Why don't you feed it into F# interactive so you can look at the types as you go:
let chrisTest test = test "Chris";;
val chrisTest : test:(string -> 'a) -> 'a
Here we have a function which we can supply another function as an argument (called test) from string -> 'a, it will call this supplied function with the argument "Chris", returning some result 'a.
let isMe x =
if x = "Chris" then
"it is Chris!"
else
"it's someone else";;
val isMe : x:string -> string
Here we have our simple name-checking function.
Notice that this isMe function is suitable to be supplied as an argument to the christTest function. Notice also that if the argument we supply chrisTest with is of type string -> string, we are going to get a string result. Hopefully you can see here how you can use the type signatures to help you reason about the behaviour of your program.
So, when we supply isMe as an argument to chrisTest, the chrisTest function runs the isMe function with the argument "Chris", returning the result "it is Chris!".
Currently reading / working my way through "Programming in Scala, First Edition", specifically Chapter 31: Combinator Parsing
The author is describing how to parse a JSON file and offers the following more advanced tranformations:
def obj: Parser[Map[String, Any]] = // Can be improved
"{"~repsep(member, ",")~"}" ^^
{ case "{"~ms~"}" => Map() ++ ms }
later improved to:
def obj: Parser[Map[String, Any]] =
"{"~> repsep(member, ",") <~"}" ^^ (Map() ++ _)
However, when I enter such code into my IDE (IntelliJ IDEA 14.03), the compiler rejects it with:
Expression of type JSON.this.type#Parser[Iterable[Any]] doesn't
conform to expected type JSON.this.type#Parser[Map[String,Any]]
I can, of course, make this error go away by changing obj's type to Parser[Iterable[Any]], but this doesn't give the desired result.
What is the correct way to do this?
For whatever it is worth, I'm using jdk 1.7.0_71 and sdk 2.11.5
It depends on the parser for "member".
I guess you are using a parser like:
def member: Parser[Any]
Like in the example, try to use the member parser:
def member: Parser[(String, Any)] =
stringLiteral~":"~value ^^
{ case name~":"~value => (name, value) }
I'm trying to figure out Haskell's json library. However, I'm running into a bit of an issue in ghci:
Prelude> import Text.JSON
Prelude Text.JSON> decode "[1,2,3]"
<interactive>:1:0:
Ambiguous type variable `a' in the constraint:
`JSON a' arising from a use of `decode' at <interactive>:1:0-15
Probable fix: add a type signature that fixes these type variable(s)
I think this has something to do with the a in the type signature:
decode :: JSON a => String -> Result a
Can someone show me:
How to decode a string?
What's going with the type system here?
You need to specify which type you want to get back, like this:
decode "[1,2,3]" :: Result [Integer]
-- Ok [1,2,3]
If that line was part of a larger program where you would go on and use the result of decode the type could just be inferred, but since ghci doesn't know which type you need, it can't infer it.
It's the same reason why read "[1,2,3]" doesn't work without a type annotation or more context.
The decode function is defined as follows:
decode :: JSON a => String -> Result a
In a real program, the type inference engine can usually figure out what type to expect from decode. For example:
userAge :: String -> Int
userAge input = case decode input of
Result a -> a
_ -> error $ "Couldn't parse " ++ input
In this case, the type of userAge causes the typechecker to infer that decode's return value, in this particular case, is Result Int.
However, when you use decode in GHCi, you must specify the type of the value, e.g.:
decode "6" :: Result Int
=> Ok 6
A quick glance at the docs seems to suggest that the purpose of this function is to allow you to read JSON into any Haskell data structure of a supported type, so
decode "[1, 2, 3]" :: Result [Int]
ought to work