Suave Experimental Form select-input - f#

I'm extending the tutorial at http://vgaltes.com/suave/forms-with-suave-experimental-and-suave-forms/ to support a HTML select-input/drop down list.
divAttr ["class", "editor-field"] [
input (fun f -> <# f.Name #>) [] Forms.human
]
The problem is that divAttr expects a Xml type, but Suave.Form.input returns a Node. Does anyone know how to solve this or have an example of how to do a select-input that can be added to divAttr?
I have looked at one example of how to do this, from the Suave Music Store book. But that seems to be outdated, and not relevant to the latest version of Suave.
I'm running Suave & Suave.Experimental 2.1.0.
Thanks!

The latest version of Suave and Suave.Experimental (2.1.1) the code is div, not divAttr, and div expects a Node so I believe that'll fix your issue.

Related

F# Fake globbing operator and MSBuild

I'm learning Fake 5 (F# Make) and I'm going through the Getting Started tutorial. When I run the following code I receive an error message : tryscript.fsx (6,7)-(6,54): Error FS0001: The type 'Fake.IO.IGlobbingPattern' is not compatible with the type 'seq<'a>'
#r "paket: nuget Fake.IO.FileSystem //"
open Fake.IO.Globbing.Operators
let csProjectFiles = !! "src/app/**/*.csproj"
csProjectFiles
|> Seq.iter (fun x -> printfn "ProjectFile: %s" x)
// for projectFile in csProjectFiles do
// printfn "F# ProjectFile: %s" projectFile
But if I comment out two lines starting at csProjectFiles |> ... and uncomment the last two lines I will get the expected output of file names.
According to documentation and Ionide tooltips the !! should return a sequence of file names. Can someone advise me what I might be doing wrong?
P.S. I'm using Fake 5.3.1 installed using dotnet tool install fake-cli -g
UPD. I don't have any solution for this issue. It resolved itself after Windows 10 got an update and I removed Nuget package caches in %HOMEPATH\.nuget, %HOMEPATH%\AppData\Local\Nuget, and deleted .fake folder and lock file in the same folder as FAKE script and then reran script again.
If you are still facing similar issue developers ask for extended log fake -vv run <yourScriptName>.fsx after you clear all the caches, and archived contents of %HOMEPATH%\.nuget\packages\netstandard.library after this run.
Just for completeness sake, the reported issue can be found here: https://github.com/fsharp/FAKE/issues/2062
If anyone encounters this issue please open a new issue (and link the old one) and provide the following information:
Can you clean everything and send the output of fake -vv run tryscript.fsx and attach the logfile? Something is indeed fishy with the NetStandard.Library package
Can you also compress and attach the folder C:\Users\.nuget\packages\netstandard.library and then try to delete it (and again create a logfile for that)?
I'd assume this was either a caching issue or an F# compiler bug or both.

Fake Glob operator (!!) not expanding directory paths

I have a situation where in a Fake script I am trying to grab all the unit test dll's from a path using the Glob (!!) operator.
The issue is that on my machine the glob expansion doesn't work, on other similar Windows 10 machines at work, its fine and finds the dlls.
Below is an example:
let path = [function to generate path]
trace path [would look something like "c:\git\project\src\**\*UnitTest*"]
!! path.ToLower()
|> Seq.iter (fun file -> trace file ) [this would not output anything]
I've tried numerous things:
uninstalling older versions of F#
reinstalling the lastest version
ensuring F# is in my Path
The versions of software I am using are:
Fake v4.63.2
Windows 10
F#4.1
No errors or exceptions are thrown.
Whats the best way to trouble shoot if its an F# or a Fake issue?
How could I work out what version of F# Fake is using?
Update
I've reinstalled F# 4.1 and performed a test using fsi.exe with the following command:
Microsoft (R) F# Interactive version 4.1
<snip>
#r #"packages/FAKE/tools/FakeLib.dll";;
open Fake;;
!! "**\*UnitTests.dll" |> Seq.iter (fun x -> trace x);;
C:\git\project1\bin\Debug\project1.UnitTests.dll
C:\git\project2\bin\Debug\project2.UnitTests.dll
!! "**\*UnitTests.dll".ToLower() |> Seq.iter (fun x -> trace x);;
C:\git\project1\bin\Debug\project1.UnitTests.dll
C:\git\project2\bin\Debug\project2.UnitTests.dll
All the test dlls were found, both with and without the call to ToLower().
When I remove the ToLower() from the script, it now works on my machine.
However, on other peoples machines removing ToLower() on the path causes them not to find any files.
So, is Fake using a different version of the fsi.exe?
I've opened a github issue to see if that sheds any light on it: https://github.com/fsharp/FAKE/issues/1772
In F# as in all .NET languages, the backslash is used for escape sequences in strings.
You need to escape the backslash or use a verbatim string, eg :
let path = "c:\\git\\project\\src\\**\\*UnitTest*"
or
let path = #"c:\git\project\src\**\*UnitTest*"
Fake can work with forward slashes as well :
let path = "c:/git/project/src/**/*UnitTest*"
You'll have to use forward slashes anyway if you want your build script to run on Linux.
An even better option is to use relative paths. Your build script most likely is stored in your project folder. You can write
let path = "src/**/*UnitTest*"
Using the following script, I was able to reproduce the issue and work out that the issue was due to how Windows 10 handles the original casing of the company name, in the path.
I confirmed this by changing company name to ** in the file path expression, the operator worked and found all the dlls.
I remember changing the capitalisation of the company name, from all caps to lower case. If I remove the ToLower() on the path, then the script works fine and finds all the dlls.
This hidden issue, combined with how FAKE does a case sensitive search, doesn't help either.
Powershell
packages\FAKE\tools\FAKE.exe glob.test.fsx
glob.test.fsx
#r #"packages/FAKE/tools/FakeLib.dll"
open Fake
let thePath = """C:\git\company/projectname/**/bin/Debug/*UnitTests.dll"""
sprintf "the path is %s" thePath |> trace
!! thePath.ToLower() |> Seq.iter (fun f -> trace f)
I had a look at the process executing in ProcMon and did not see the original casing of the directory. The NTFS file system is still see this directory as its original casing (see comments below).
I re-image my machine every few months, so this will disappear soon but it was good to understand what was going on.
Thanks to all those that helped narrow the issue down.

How to turn off Ionide Lint warnings

I have written a F# script in FSI using Ionide in VS Code. It's a great tool, but I am getting a warning from Ionide Lint suggesting a code improvement:
'Lint: Seq.map f (Seq.map g x) might be able to be refactored into Seq.map (g >> f) x.'
I have about 6 Seq.map functions all piped together with |> which I am happy with.
There is also a green wiggly line that is annoying me. I don't agree with the suggestion, and want the wiggly line to go away. How can I tell Ionide to stop making this suggestion?
I have turned off Lint globally in the VS Code settings
"FSharp.linter": false,
I think Ionide uses FsharpLint: http://fsprojects.github.io/FSharpLint/
This supports suppressing of lint messages like this:
[<SuppressMessage("NameConventions", "InterfaceNamesMustBeginWithI")>]
type Printable =
abstract member Print : unit -> unit
Something like that might work for you as well. I just turned it off.
This is the directive to disable this particular message in code:
open System.Diagnostics.CodeAnalysis
[<SuppressMessage("Hints", "") >]
Place above the block that is producing this 'error'.

How to handle pathScan decoding of url encoded parameters?

I have something like :-
pathScan "/blah/%s" (fun x) -> (sprintf "%A" x) |> json)
and what it shows me if I do /blah/AT%2BVER%3F is the url encoded data. Is there a way to get this decoded automatically? or do I need to parse all my parameters ( which seems a bit odd )
Some older versions require manually decoding. Note that a pull request was accepted (and is now in the current release) which should address this in the next release.
Currently, the best option is to either upgrade to the latest Suave or run this through System.Web.HttpUtility.UrlDecode yourself (as this is the mechanism being used by Suave vCurrent).

Stream reasoning / Reactive programming in prolog?

I was wondering if you know of any way to use prolog for stream processing, that is, some kind of reactive programming, or at least to let a query run on a knowledge base that is continuously updated (effectively a stream), and continuously output the output of the reasoning?
Anything implemented in the popular "prologs", such as SWI-prolog?
You can use Logtalk's support for event-driven programming to define monitors that watch for knowledge base update events and react accordingly. You can run Logtalk using most Prolog systems as the backed compiler, including SWI-Prolog.
The event-driven features are described e.g. in the user manual:
http://logtalk.org/manuals/userman/events.html
The current distribution contains some examples of using events and monitors. An interesting one considering your question is the bricks example:
https://github.com/LogtalkDotOrg/logtalk3/tree/master/examples/bricks
Running this example first and then looking at its code should give you as good idea of what you can do with system wide events and monitors.
XSB has stream processing capabilities. See page 14 in the
XSB Manual
I'm working on something related, in project pqConsole already there is the basic capability: report to the user structured data, containing actionable areas (links) that call back in Prolog current state, hence the possibility to expose actions and react appropriately (hopefully).
It's strictly related to pqConsole::win_write_html, showcasing recent Qt capabilities of SWI-Prolog.
Here an example of a snippet producing only a simple formatted report, I'll try now to add the reactive part, so you can evaluate if you find expressive this basic system. Hints are welcome...
/* File: win_html_write_test.pl
Author: Carlo,,,
Created: Aug 27 2013
Purpose: example usage win_html_write/1
*/
:- module(win_html_write_test,
[dir2list/1
]).
:- [library(http/html_write)].
:- [library(dirtree)].
dir2list(Path) :-
dirtree(Path, DirTree),
% sortree(compare_by_attr(name), DirTree, Sorted), !,
DirTree = Sorted,
phrase(html([\css,
\logo,
hr([]),
ul(\dirtree2html(Sorted, [])),
br([])]), Tokens),
with_output_to(atom(X), print_html(Tokens)),
win_html_write(X),
dump_page_to_debug(X).
css --> html(style(type='text/css',
['.size{color:blue;}'
])).
logo --> html(img([src=':/swipl.png'],[])).
dirtree2html(element(dir, A, S), Parents) -->
html(li([\elem2html(A),
ul(\elements2html(S, [A|Parents]))])).
dirtree2html(element(file, A, []), _Parents) -->
html(li(\elem2html(A))).
elem2html(A) -->
{memberchk(name=N, A),
memberchk(size=S, A)
},
html([span([class=name], N), ' : ', span([class=size], S)]).
elements2html([E|Es], Parents) -->
dirtree2html(E, Parents),
elements2html(Es, Parents).
elements2html([], _Parents) --> [].
dump_page_to_debug(X) :-
open('page_to_debug.html', write, S),
format(S, '<html>~n~s~n</html>~n', [X]),
close(S).
This snippet depends on dirtree, that should be installed with
?- pack_install(dirtree).
edit With 3 modifications now the report has the ability to invoke editing of files:
call to get paths in structure
dir2list(Path) :-
dirtree(Path, DirTreeT),
assign_path(DirTreeT, DirTree),
...
request a specialized output for files only
dirtree2html(element(file, A, []), _Parents) -->
html(li(\file2html(A))).
finally, the 'handler' - here just place a request to invoke the editor
file2html(A) -->
{memberchk(name=N, A),
memberchk(path=P, A),
memberchk(size=S, A)
},
html([span([class=name],
[a([href='writeln(editing(\'~s\')), edit(\'~s\')'-[N,P]], N)]
), ' : ', span([class=size], S)]).
and now the file names are clickable, write a message and get edited if requested: a picture
You should check out RTEC: Run-Time Event Calculus:
https://github.com/aartikis/RTEC
RTEC is an open-source Event Calculus dialect optimised for stream reasoning. It is written in Prolog and has been tested under YAP 6.2.
Feature highlights:
Interval-based.
Sliding window reasoning.
Interval manipulation constructs for non-inertial fluents.
Caching for hierarchical knowledge bases.
Support for out-of-order data streams.
Indexing for handling efficiently irrelevant data.
There is also a mention of it on the SWI-Prolog website:
https://www.swi-prolog.org/pack/file_details/prologmud_I7/prolog/ec_planner/RTEC/README.md
which presumably relies on:
https://www.swi-prolog.org/pldoc/doc/_SWI_/library/dialect/yap.pl
I don't know why this hasn't been brought up so far, but in SWI-Prolog there is prolog_listen, which can, amongst other things, monitor dynamic updates to the database:

Resources