How to set an attribute of a Dom element - ocaml

I have created a td element with a call such as:
let td = Dom_html.createTd doc in
I would now like to set an attribute on this object. I have tried this:
td#setAttribute (Js.string "colspan") (Js.string "4")
But I get the error:
Error: This expression has type Dom_html.tableCellElement Js.t
It has no method setAttribute

Simple dash # is used to access method of OCaml object.
Js_of_ocaml has a special syntax (##) to deal with Javascript object.
see http://ocsigen.org/js_of_ocaml/2.4/manual/library
To set an attribute of a dom element:
td##setAttribute(Js.string "key", Js.string "val")
In you case you should rather use :
td##colSpan <- 4
The double dash ## will translate JavaScript field access.
The previous statement translates to td.colSpan = 4.
The type parameter 'a in 'a Js.t is a phantom type used by the type checker to check JavaScript field access. see http://ocsigen.org/js_of_ocaml/2.4/api/Dom_html.tableCellElement-c in your case.

Related

ocamldoc not properly displaying parameter names or description with #param

Simply put, let us say I have the following OCaml file called test.ml:
(**
[Test] is a sample module for showing the problem I am having with # tags with OCamlDoc
*)
(**
[id] is the identity function. For any argument [x], [id x] is [x].
#param x The argument, which will be returned
#return The argument [x]
*)
let id (x: 'a): 'a = x
If I run the command ocamldoc -html -all-params -colorize-code test.ml to get the documentation for the Test module, I get the following result:
As can be seen, for the parameter information, it puts () as the name of the parameter and does not include a description for the parameter for some reason.
I am unsure why the parameter name and description are not properly showing up.
If you write let id x = x the display is correct:
The problem is that ocamldoc will not display #param if you provide a tag that doesn't match a named argument but it's not able to extract a named argument from (id : type).
This is a known bug but sadly nobody touched it so... https://github.com/ocaml/ocaml/issues/8804
As ocamldoc's part-time maintainer, there are very few reasons to still use ocamldoc when odoc is available, even more so when writing new documentation.
Ocamldoc's handling of param tag is far too complex for its own good: ocamldoc tries to peek at the definition of the function and only accepts param tag that matches the argument that it can recognize. Here, it fails on explicit type annotation.

Converting Powershell Array to Text so it can be exported to CSV or HTML

I'm trying to convert the output of a powershell (AWS Tools) command to strings so that I can export them to CSV or HTML. I for the life of me can't figure it out. I've seen comments on hashtables, naming elements, etc. Nothing seems to help me. (I'm very much a newbie).
This is what I got.
This command
(Get-IAMAccountAuthorizationDetail).UserDetailList | Select UserName, Grouplist
Will output this (with better spacing):
UserName GroupList
-------- ---------
User1 {Admins,Test}
User2 {Admins}
I cant' seem to figure out how to get this data so that it can be converted to CSV or HTML. Those brackets are an indication its an object, array or something. Can someone show me the code that would convert this to text or something that the Convertto-CVS o Convertto-HTML commands would work.
The output (subset) of the Get-Member Command is this:
TypeName : Amazon.IdentityManagement.Model.UserDetail
Name : Equals
MemberType : Method
Definition : bool Equals(System.Object obj)
TypeName : Amazon.IdentityManagement.Model.UserDetail
Name : GetHashCode
MemberType : Method
Definition : int GetHashCode()
TypeName : Amazon.IdentityManagement.Model.UserDetail
Name : GroupList
MemberType : Property
Definition : System.Collections.Generic.List[string] GroupList {get;set;}
Thanks
You could do something like the following, which will create a semi-colon delimited list within the GroupList cell:
(Get-IAMAccountAuthorizationDetail).UserDetailList |
Select-Object UserName,#{n='GroupList';e={$_.Grouplist -join ';'}}
Explanation:
The syntax #{n='Name';e={Expression}} is called a calculated property as explained at Select-Object. Here is some information about the calculated property:
It is a hash table with custom properties.
The first property is Name, which is a label for your expression output. n,Name,l, and label are all acceptable property names for that property.
The value passed to n is just a string that you are creating. It is the property name that will show up in your output, and it does not need to already exist in your object. Your actual property is called GroupList. As an example with n='All The Groups', the property name would becomeAll The Groups` in your output. There is nothing wrong with reusing the same name the property currently has.
The Expression or e is the ScriptBlock, which is why it is surrounded by {}. The ScriptBlock is responsible for producing the value in your custom property.
$_ is the current pipeline object passed into the ScriptBlock. This means if you have a collection (just like you do in your case), $_ will represent each of those items in order.
If you want to add another calculated property, just add a comma after the last and use the calculated property syntax like so:
Select-Object #{n='CustomProperty1';e={$_.ObjectProperty1}},#{n='CustomProperty2';e={$_.ObjectProperty2}}

What is this syntax: template tplname{op(id,[id2])}(params)

In the json module:
template simpleGetOrDefault*{`{}`(node, [key])}(node: JsonNode, key: string): JsonNode = node.getOrDefault(key)
What's up with the curly braces (and what's that in them) ?
This is an example of a "term-rewriting macro".
A bit earlier in the json module, you'll find the definition of the {} operator with the following signature:
proc `{}`*(node: JsonNode, keys: varargs[string]): JsonNode =
## Traverses the node and gets the given value. If any of the
## keys do not exist, returns ``nil``. Also returns ``nil`` if one of the
## intermediate data structures is not an object.
The goal of the term-rewriting macro is to intercept the case where only a single string is given as argument to the operator and to turn this into a simple call to getOrDefault.

How to sequence a query in F#?

So I have a query like this one
let query =
query {
for person in people do
select person
}
And I'd like to have it sequenced.
let sequence : seq<Person> = query
But I can't find any information on how to do it, maybe I've become bad at using search engines.
I'm getting unexpected type compiling expections using things like |> seq.ofList and ToList().
The expression was expected to have the type seq<Person> but here has the type Generic.List<Person>.
The result of a query expression has type IQueryable<_>, which is a subtype of IEnumerable<_> (for which seq<_> is a synonym), so you can simply change the type:
let mySeq : seq<_> = myQuery
Or, if you want to avoid a type annotation, use the built-in seq function, which does the same thing:
let mySeq = seq myQuery

Explanation why a list with different types is a valid Haskell expression needed

So in an exercise I am given a list like ["xyz", True, 42]. The question was if that is a valid expression in Haskell and what the type of that expression is.
A list can only hold homogenous types but the type of "xyz"is [Char], the type of True is Bool and the type of 42 is Num p => p. That is different types so I can't put them into a list.
That's what I thought. But the given answer to that exercise is "Yes, it is a valid expression. Show-instance!."
Why is it a valid expression although the types of the list elements are different and what is meant with show-instance? I'm thinking of something like superclasses from object oriented languages but I thought this is not how Haskell works.
If we are allowed to define some more context, we can make this a valid expression, for instance with:
import Data.String(IsString(fromString))
instance IsString Bool where
fromString [] = False
fromString _ = True
instance Num Bool where
(+) = (||)
(*) = (&&)
abs = id
signum = id
fromInteger 0 = False
fromInteger _ = True
negate = not
(here I used the truthiness of Python to convert from an Integer and String literal)
Then we can write it with the OverloadedStrings pragma:
{-# LANGUAGE OverloadedStrings #-}
the_list = ["xyz", True, 42]
This will then be equivalent to:
Prelude Data.String> ["xyz", True, 42]
[True,True,True]
But note that the list still contains only Bools, we only made Bool an instance of IsString and Num to enable us to convert string literals and number literals to Bools.
A list of heterogeneous types is not possible in Haskell, and since by default a Bool is not a Num, we thus can not parse that expression without adding some extra magic.
An additional note is that it is valid Haskell grammar: syntactically there is nothing wrong, it is only in the next stage of the compiler: type checking, etc. that it will raise errors, since the syntax is nonsensical.
My lecturer gave me a hint to check for Existential types in Haskell.
I produced a working example from the description from the link above:
{-# LANGUAGE ExistentialQuantification #-}
module Main where
data Showable = forall a . Show a => MkShowable a
pack:: Show a => a -> Showable
pack a= MkShowable a
instance Show Showable where
show (MkShowable a) = show a
hlist :: [Showable]
hlist = [pack "xyz", pack True, pack 42]
main :: IO ()
main = do
putStrLn "Heterogenous list 'camouflaged' as Showable:"
print hlist
This works and produces indeed the input from the exercise. The datatype extension for Existential Quantification in the first line is necessary.
My explanation (I might have gotten something wrong though):
I create a new type Showablewith one constructor MkShowable that takes any value a as long as it is in typeclass Show and thus makes a Showable out of it.
The method pack makes a Show a become a Showable by using the constructor MkShowable I described in 1.
Showable is made an instance of Show-typeclass and tells that if a Showable(MkShowable a) is to be shown, simply show a. So we can easily print our Showables.
Furthermore I created a (heterogenous) list hlist of type [Showable]and packed the values from my example into it, using pack. The list is printed in the main function.
This really reminds me of object-oriented programming.