How do I get keepWhen behaviour in Elm 0.15? - functional-programming

The keepWhen function from earlier versions of Elm was removed. I have ported an Elm application from 0.14, but I'm stuck at trying to get one part of it to work, where it's using keepWhen.
So basically I'm looking for a function like
keepWhen : Signal Bool -> a -> Signal a -> Signal a
I have found
filter : (a -> Bool) -> a -> Signal a -> Signal a
but it's not quite the same thing, and I haven't figured out how to get it to work.

Answer: import it from a utility package
The easiest way is to use Signal.Extra.keepWhen from the signal-extra package.
(full disclosure: I'm the author)
Important implementation detail
Notice that the implementation isn't completely trivial. This is the implementation in the package (the Signal module is imported unqualified):
keepWhen : Signal Bool -> a -> Signal a -> Signal a
keepWhen boolSig a aSig =
zip boolSig aSig
|> sampleOn aSig
|> keepIf fst (True, a)
|> map snd
The important difference with the version in kqr's answer is the sampleOn which keeps the output of keepWhen from updating when the boolean input changes. The difference between the two filters is that the keepWhen from 0.14 really only filters update events from the a input and doesn't sample it when the boolean input becomes True.
The other implementation is also in signal-extra under the name sampleWhen.
Diagrams
If you know a little about marble diagrams, maybe these old diagrams may help. I'll just post a screenshot of the relevant ones below.
The way you read these diagrams:
Time flows from left to right.
A line is a signal.
The block is a function that takes the two signals above and produces the signal below.
The shape at the left of each line is the initial value.
A filled shape is an event on a signal.
An outlined shape is for when the signal doesn't change.
I've used shapes to represent types.
I've used colours to represent different values.
Note that the second diagram, labeled as old behaviour, matches the behaviour of the code in kqr's answer.

I have reimplemented keepWhen in terms of Signal.filter in Elm 0.15. This rests on the observation that Signal.filter uses the value of the signal to decide whether to drop or keep the signal value, and the fact that you can combine two signals to get a new signal (Signal.map2 (,)).
If you combine the Signal Bool you have with the Signal a you eventually want, you'll get a Signal (a, Bool) where you can, in the Signal.filter, just extract the Bool value to decide whether or not you want to keep that value.
The function looks like this:
keepWhen : Signal Bool -> a -> Signal a -> Signal a
keepWhen cond def val =
let combined = Signal.map2 (,) val cond
filtered = Signal.filter snd (def, False) combined
final = Signal.map fst filtered
in final
It first pairs up the "value" signal with the Bool signal to get a Signal (a, Bool). Then it filters that signal based on the Bool in it, and finally it strips off the Bool and keeps only the "real" value.
You can see it working here: http://share-elm.com/sprout/553c01afe4b06aacf0e8985a . If you have the mouse close to the (0,0) corner it will not update, but when you move the mouse farther to the bottom right it will start updating the signal again.

Related

Trying to use ConcatLayer with different shape inputs

I am trying to work with nolearn and use the ConcatLayer to combine multiple inputs. It works great as long as every input has the same type and shape. I have three different types of inputs that will eventually produce a single scalar output value.
The first input is an image of dimensions (288,1001)
The second input is a vector of length 87
The third is a single scalar value
I am using Conv2DLayer(s) on the first input.
The second input utilizes Conv1DLayer or DenseLayer (not sure which would be better since I can't get it far enough to see what happens)
I'm not even sure how the third input should be set up since it is only a single value I want to feed into the network.
The code blows up at the ConcatLayer with:
'Mismatch: input shapes must be the same except in the concatenation axis'
It would be forever grateful if someone could write out a super simple network structure that can take these types of inputs and output a single scalar value. I have been googling all day and simply cannot figure this one out.
The fit function looks like this if it is helpful to know, as you can see I am inputting a dictionary with an item for each type of input:
X = {'base_input': X_base, 'header_input': X_headers, 'time_input':X_time}
net.fit(X, y)
It is hard to properly answer the question, because - it depends.
Without having information on what you are trying to do and what data you are working on, we are playing the guessing game here and thus I have to fall back to giving general tips.
First it is totally reasonable, that ConcatLayer complains. It just does not make a lot of sense to append a scalar to the Pixel values of an Image. So you should think about what you actually want. This is most likely combining the information of the three sources.
You are right by suggesting to process the Image with 2D convolutions and the sequence data with 1D convolutions. If you want to generate a scalar value, you propably want to use dense layers later on, to condense the information.
So it would be naturally, to leave the lowlevel processing of the three branches independent and then concatenate them later on.
Something along the lines of:
Image -> conv -> ... -> conv -> dense -> ... -> dense -> imValues
Timeseries -> conv -> ... -> conv -> dense ... -> dense -> seriesValues
concatLayer([imValues, seriesValues, Scalar] -> dense -> ... -> dense with num_units=1
Another less often reasonable Option would be, to add the Information at the lowlevel processing of the Image. This might make sense, if the local processing is much easier, given the knowledge of the scalar/timeseries.
This architecture might look like:
concatLayer(seriesValues, scalar) -> dense -> ... -> reshape((-1, N, 1, 1))
-> Upscale2DLayer(Image.shape[2:3]) -> globalInformation
concatLayer([globalInformation, Image]) -> 2D conv filtersize=1 -> conv -> ... -> conv
Note that you will almost certainly want to go with the first Option.
One unrelated Thing I noticed, is the huge size of your Input Image. You should reduce it(resizing/patches). Unless you have a gigantic load of data and tons of Memory and computing power, you will otherwise either overfit or waste Hardware.

Elm: understanding foldp and mouse-clicks

I'm currently learning Elm. relatively new to functional programming. i'm trying to understand this example from http://elm-lang.org/learn/Using-Signals.elm on counting mouse-clicks. they provide the following code:
clickCount =
foldp (\click count -> count + 1) 0 Mouse.clicks
They explain that foldp takes three arguments: a counter-incrementer, which we defined as an anonymous function with two inputs, a starting state 0, and the Mouse.clicks signal.
I do not understanding why we need the variable click in our anonymous function. Why can't we just have \count -> count + 1? Is the extra input getting bound to one of our inputs into foldp?
thanks!
You need it because foldp expects a function with two inputs. In this case, the first input is just ignored by your lambda, but the foldp implementation still puts something in there. Mouse.clicks always puts a sort of do-nothing value called Unit in there.
Some signals have a value associated with them, like Mouse.position, for example. If you wanted to do something like measure how far the mouse has moved, you would need to use that parameter.

Elm function with the type: Signal (List a) -> List (Signal a)

I am new to elm and functional programming in general. But I am using elm and I really need a function that has a Signal (List String) as an input and returns List (Signal String).
I know I probably shouldn't have this problem with a better architectural design in my program but having a function that could do this would solve a big problem for me.
The combine function does exactly the opposite:
combine : List (Signal a) -> Signal (List a)
combine = List.foldr (map2 (::)) (constant [])
I've tried to do something similar to the combine function but have been unsuccessful so far. Any ideas on how to create such function?
This is not possible in general
The inverse of combine is not (in general) possible.
When you have a list of static size of signals, then you can combine them into a signal of lists of static size. But when you go the other way, there is no guarantee that the lists in the signal are a static size. Therefore you cannot "just" construct a list out of it.
(If you could then a normal value of type List could have a changing size without showing Signal around the type, and you would be dynamically creating and destroying signals in the list. Those are two things Elm disallows. )
But with some restrictions...
Of course if you know that the list in the signal is of a static size, you can write a specific function based on that assumption; that function would then fail at runtime if the case occurs that your assumption of static size lists was wrong.
unsafe : Maybe a -> a
unsafeHead m =
case m of
Just a -> a
Nothing -> Debug.crash "unsafe: You're out of luck. The `Maybe` was not a `Just`. "
uncombine : Int -> Signal (List a) -> List (Signal a)
uncombine n sig =
if n == 0
then []
else Signal.map (List.head >> unsafe) sig
:: uncombine (n-1) (Signal.map (List.tail >> unsafe) sig)
(I'm quite sure this question was discussed on the elm-discuss mailing list once, but I can't find it any more)

Erlang Recursive end loop

I just started learning Erlang and since I found out there is no for loop I tried recreating one with recursion:
display(Rooms, In) ->
Room = array:get(In, Rooms)
io:format("~w", [Room]),
if
In < 59 -> display(Rooms, In + 1);
true -> true
end.
With this code i need to display the content (false or true) of each array in Rooms till the number 59 is reached. However this creates a weird code which displays all of Rooms contents about 60 times (?). When I drop the if statement and only put in the recursive code it is working except for a exception error: Bad Argument.
So basically my question is how do I put a proper end to my "for loop".
Thanks in advance!
Hmm, this code is rewritten and not pasted. It is missing colon after Room = array:get(In, Rooms). The Bad argument error is probably this:
exception error: bad argument
in function array:get/2 (array.erl, line 633)
in call from your_module_name:display/2
This means, that you called array:get/2 with bad arguments: either Rooms is not an array or you used index out of range. The second one is more likely the cause. You are checking if:
In < 59
and then calling display again, so it will get to 58, evaluate to true and call:
display(Rooms, 59)
which is too much.
There is also couple of other things:
In io:format/2 it is usually better to use ~p instead of ~w. It does exactly the same, but with pretty printing, so it is easier to read.
In Erlang if is unnatural, because it evaluates guards and one of them has to match or you get error... It is just really weird.
case is much more readable:
case In < 59 of
false -> do_something();
true -> ok
end
In case you usually write something, that always matches:
case Something of
{One, Two} -> do_stuff(One, Two);
[Head, RestOfList] -> do_other_stuff(Head, RestOfList);
_ -> none_of_the_previous_matched()
end
The underscore is really useful in pattern matching.
In functional languages you should never worry about details like indexes! Array module has map function, which takes function and array as arguments and calls the given function on each array element.
So you can write your code this way:
display(Rooms) ->
DisplayRoom = fun(Index, Room) -> io:format("~p ~p~n", [Index, Room]) end,
array:map(DisplayRoom, Rooms).
This isn't perfect though, because apart from calling the io:format/2 and displaying the contents, it will also construct new array. io:format returns atom ok after completion, so you will get array of 58 ok atoms. There is also array:foldl/3, which doesn't have that problem.
If you don't have to have random access, it would be best to simply use lists.
Rooms = lists:duplicate(58, false),
DisplayRoom = fun(Room) -> io:format("~p~n", [Room]) end,
lists:foreach(DisplayRoom, Rooms)
If you are not comfortable with higher order functions. Lists allow you to easily write recursive algorithms with function clauses:
display([]) -> % always start with base case, where you don't need recursion
ok; % you have to return something
display([Room | RestRooms]) -> % pattern match on list splitting it to first element and tail
io:format("~p~n", [Room]), % do something with first element
display(RestRooms). % recursive call on rest (RestRooms is quite funny name :D)
To summarize - don't write forloops in Erlang :)
This is a general misunderstanding of recursive loop definitions. What you are trying to check for is called the "base condition" or "base case". This is easiest to deal with by matching:
display(0, _) ->
ok;
display(In, Rooms) ->
Room = array:get(In, Rooms)
io:format("~w~n", [Room]),
display(In - 1, Rooms).
This is, however, rather unidiomatic. Instead of using a hand-made recursive function, something like a fold or map is more common.
Going a step beyond that, though, most folks would probably have chosen to represent the rooms as a set or list, and iterated over it using list operations. When hand-written the "base case" would be an empty list instead of a 0:
display([]) ->
ok;
display([Room | Rooms]) ->
io:format("~w~n", [Room]),
display(Rooms).
Which would have been avoided in favor, once again, of a list operation like foreach:
display(Rooms) ->
lists:foreach(fun(Room) -> io:format("~w~n", [Room]) end, Rooms).
Some folks really dislike reading lambdas in-line this way. (In this case I find it readable, but the larger they get the more likely the are to become genuinely distracting.) An alternative representation of the exact same function:
display(Rooms) ->
Display = fun(Room) -> io:format("~w~n", [Room]) end,
lists:foreach(Display, Rooms).
Which might itself be passed up in favor of using a list comprehension as a shorthand for iteration:
_ = [io:format("~w~n", [Room]) | Room <- Rooms].
When only trying to get a side effect, though, I really think that lists:foreach/2 is the best choice for semantic reasons.
I think part of the difficulty you are experiencing is that you have chosen to use a rather unusual structure as your base data for your first Erlang program that does anything (arrays are not used very often, and are not very idiomatic in functional languages). Try working with lists a bit first -- its not scary -- and some of the idioms and other code examples and general discussions about list processing and functional programming will make more sense.
Wait! There's more...
I didn't deal with the case where you have an irregular room layout. The assumption was always that everything was laid out in a nice even grid -- which is never the case when you get into the really interesting stuff (either because the map is irregular or because the topology is interesting).
The main difference here is that instead of simply carrying a list of [Room] where each Room value is a single value representing the Room's state, you would wrap the state value of the room in a tuple which also contained some extra data about that state such as its location or coordinates, name, etc. (You know, "metadata" -- which is such an overloaded, buzz-laden term today that I hate saying it.)
Let's say we need to maintain coordinates in a three-dimensional space in which the rooms reside, and that each room has a list of occupants. In the case of the array we would have divided the array by the dimensions of the layout. A 10*10*10 space would have an array index from 0 to 999, and each location would be found by an operation similar to
locate({X, Y, Z}) -> (1 * X) + (10 * Y) + (100 * Z).
and the value of each Room would be [Occupant1, occupant2, ...].
It would be a real annoyance to define such an array and then mark arbitrarily large regions of it as "unusable" to give the impression of irregular layout, and then work around that trying to simulate a 3D universe.
Instead we could use a list (or something like a list) to represent the set of rooms, but the Room value would now be a tuple: Room = {{X, Y, Z}, [Occupants]}. You may have an additional element (or ten!), like the "name" of the room or some other status information or whatever, but the coordinates are the most certain real identity you're likely to get. To get the room status you would do the same as before, but mark what element you are looking at:
display(Rooms) ->
Display =
fun({ID, Occupants}) ->
io:format("ID ~p: Occupants ~p~n", [ID, Occupants])
end,
lists:foreach(Display, Rooms).
To do anything more interesting than printing sequentially, you could replace the internals of Display with a function that uses the coordinates to plot the room on a chart, check for empty or full lists of Occupants (use pattern matching, don't do it procedurally!), or whatever else you might dream up.

How do I detect circular logic or recursion in a custom expression evaluator?

I've written an experimental function evaluator that allows me to bind simple functions together such that when the variables change, all functions that rely on those variables (and the functions that rely on those functions, etc.) are updated simultaneously. The way I do this is instead of evaluating the function immediately as it's entered in, I store the function. Only when an output value is requested to I evaluate the function, and I evaluate it each and every time an output value is requested.
For example:
pi = 3.14159
rad = 5
area = pi * rad * rad
perim = 2 * pi * rad
I define 'pi' and 'rad' as variables (well, functions that return a constant), and 'area' and 'perim' as functions. Any time either 'pi' or 'rad' change, I expect the results of 'area' and 'perim' to change in kind. Likewise, if there were any functions depending on 'area' or 'perim', the results of those would change as well.
This is all working as expected. The problem here is when the user introduces recursion - either accidental or intentional. There is no logic in my grammar - it's simply an evaluator - so I can't provide the user with a way to 'break out' of recursion. I'd like to prevent it from happening at all, which means I need a way to detect it and declare the offending input as invalid.
For example:
a = b
b = c
c = a
Right now evaluating the last line results in a StackOverflowException (while the first two lines evaluate to '0' - an undeclared variable/function is equal to 0). What I would like to do is detect the circular logic situation and forbid the user from inputing such a statement. I want to do this regardless of how deep the circular logic is hidden, but I have no idea how to go about doing so.
Behind the scenes, by the way, input strings are converted to tokens via a simple scanner, then to an abstract syntax tree via a hand-written recursive descent parser, then the AST is evaluated. The language is C#, but I'm not looking for a code solution - logic alone will be fine.
Note: this is a personal project I'm using to learn about how parsers and compilers work, so it's not mission critical - however the knowledge I take away from this I do plan to put to work in real life at some point. Any help you guys can provide would be appreciated greatly. =)
Edit: In case anyone's curious, this post on my blog describes why I'm trying to learn this, and what I'm getting out of it.
I've had a similar problem to this in the past.
My solution was to push variable names onto a stack as I recursed through the expressions to check syntax, and pop them as I exited a recursion level.
Before I pushed each variable name onto the stack, I would check if it was already there.
If it was, then this was a circular reference.
I was even able to display the names of the variables in the circular reference chain (as they would be on the stack and could be popped off in sequence until I reached the offending name).
EDIT: Of course, this was for single formulae... For your problem, a cyclic graph of variable assignments would be the better way to go.
A solution (probably not the best) is to create a dependency graph.
Each time a function is added or changed, the dependency graph is checked for cylces.
This can be cut short. Each time a function is added, or changed, flag it. If the evaluation results in a call to the function that is flagged, you have a cycle.
Example:
a = b
flag a
eval b (not found)
unflag a
b = c
flag b
eval c (not found)
unflag b
c = a
flag c
eval a
eval b
eval c (flagged) -> Cycle, discard change to c!
unflag c
In reply to the comment on answer two:
(Sorry, just messed up my openid creation so I'll have to get the old stuff linked later...)
If you switch "flag" for "push" and "unflag" for "pop", it's pretty much the same thing :)
The only advantage of using the stack is the ease of which you can provide detailed information on the cycle, no matter what the depth. (Useful for error messages :) )
Andrew

Resources