Storing a closure in a structure — cannot infer an appropriate lifetime - closures

I'm trying to implement the State monad in Rust (State is effectively a wrapper over a function which takes original state and returns modified state and some result). This is how one can implement State in Haskell (monad operations where renamed to unit and bind for sake of simplicity):
data State s u = State { run :: s -> (u, s) }
-- return
unit :: u -> State s u
unit u = State $ \s -> (u, s)
-- (>>=)
bind :: State s u -> (u -> State s a) -> State s a
bind m f = State $ \s ->
let (u, s') = run m s
in run (f u) s'
So I try to rewrite it in Rust:
pub struct State<'r, S, U> {
priv run: 'r |S| -> (U, S)
}
pub fn unit<'r, S, U>(value: U) -> State<'r, S, U> {
State {
run: |state| (value, state)
}
}
(Actually I'm not sure if the definition of the run field is legal — it's said to be a bug).
This code doesn't compile:
/some/path/lib.rs:31:12: 31:36 error: cannot infer an appropriate lifetime due to conflicting requirements
/some/path/lib.rs:31 run: |state| (value, state)
^~~~~~~~~~~~~~~~~~~~~~~~
/some/path/lib.rs:29:52: 33:2 note: first, the lifetime cannot outlive the block at 29:51...
/some/path/lib.rs:29 pub fn unit<'r, S, U>(value: U) -> State<'r, S, U> {
/some/path/lib.rs:30 State {
/some/path/lib.rs:31 run: |state| (value, state)
/some/path/lib.rs:32 }
/some/path/lib.rs:33 }
/some/path/lib.rs:31:12: 31:36 note: ...so that closure does not outlive its stack frame
/some/path/lib.rs:31 run: |state| (value, state)
^~~~~~~~~~~~~~~~~~~~~~~~
/some/path/lib.rs:29:52: 33:2 note: but, the lifetime must be valid for the lifetime &'r as defined on the block at 29:51...
/some/path/lib.rs:29 pub fn unit<'r, S, U>(value: U) -> State<'r, S, U> {
/some/path/lib.rs:30 State {
/some/path/lib.rs:31 run: |state| (value, state)
/some/path/lib.rs:32 }
/some/path/lib.rs:33 }
/some/path/lib.rs:30:5: 30:10 note: ...so that types are compatible (expected `State<'r,S,U>` but found `State<,S,U>`)
/some/path/lib.rs:30 State {
^~~~~
error: aborting due to previous error
Seems like I need to explicitly specify the lifetime for the closure expression when instantiating State in unit, but I just don't know how, so I need help here. Thanks.
EDIT: Unfortunately, I cannot use procs (as Vladimir suggested), because a State can be executed arbitrary number of times.

The error is completely legitimate. Currently it is completely impossible to return closures which can be called multiple times from functions (unless they were passed to these functions as arguments).
You can easily find out that you have made a mistake in lifetimes usage when you look for lifetime annotations position. When lifetime parameter is used only in arguments or only in return values, then there is a mistake in your code. This is exactly your case - unit has 'r lifetime parameter, but it is used only in return value.
Your code fails to compile because you're creating stack closure and are trying to store it inside an object which will be returned to the caller. But the closure is created on the stack, and when you return from the function, that stack space is invalidated, i.e. your closure is destroyed. Borrow checker prevents this.
Currently there are only two kinds of closures in Rust - stack boxed closures and one-off heap boxed closures (procs). You could do what you want with a proc, but you will be able to call it only once. I'm not sure if this is OK for your needs, but here you go:
pub struct State<S, U> {
priv run: proc(S) -> (U, S)
}
pub fn unit<S: Send, U: Send>(value: U) -> State<S, U> {
State {
run: proc(state) (value, state)
}
}
I had to add Send kind because procs need their environment to be sendable.
In future, when (or if) dynamically sized types land, you will be able to create regular boxed closure which can be called multiple times and which own their environment. But DST are still in design and development.

Related

Why does F# require type placeholders for ToDictionary?

given
[
1,"test2"
3,"test"
]
|> dict
// turn it into keyvaluepair sequence
|> Seq.map id
|> fun x -> x.ToDictionary<_,_,_>((fun x -> x.Key), fun x -> x.Value)
which fails to compile if I don't explicitly use the <_,_,_> after ToDictionary.
Intellisense works just fine, but compilation fails with the error: Lookup on object of indeterminate type based on information prior to this program point
So, it seems, Intellisense knows how to resolve the method call.
This seems to be a clue
|> fun x -> x.ToDictionary<_,_>((fun x -> x.Key), fun x -> x.Value)
fails with
Type constraint mismatch.
The type 'b -> 'c is not compatible with type IEqualityComparer<'a>
The type 'b -> 'c' is not compatible with the type 'IEqualityComparer<'a>'
(using external F# compiler)
x.ToDictionary((fun x -> x.Key), id)
works as expected as does
let vMap (item:KeyValuePair<_,_>) = item.Value
x.ToDictionary((fun x -> x.Key), vMap)
I've replicated the behavior in FSI and LinqPad.
As a big fan of and avid reader of Eric Lippert I really want to know
what overload resolution, (or possibly extension methods from different places) are conflicting here that the compiler is confused by?
Even though the types are known ahead, the compiler's getting confused between the overload which takes an element selector and a comparer. The lambda compiles to FSharpFunc rather than the standard delegate types in C# like Action or Func, and issues do come up translating from one to the other. To make it work, you can :
Supply a type annotation for the offending Func
fun x -> x.ToDictionary((fun pair -> pair.Key), (fun (pair : KeyValuePair<_, _>) -> pair.Value)) //compiles
or name the argument as a hint
fun x -> x.ToDictionary((fun pair -> pair.Key), elementSelector = (fun (pair) -> pair.Value))
or force it to pick the 3 argument version:
x.ToLookup((fun pair -> pair.Key), (fun (pair) -> pair.Value), EqualityComparer.Default)
Aside
In your example,
let vMap (item:KeyValuePair<_,_>) = item.Value
x.ToDictionary((fun x -> x.Key), vMap)
you would explicitly need to annotate vMap because the compiler cannot find out what type the property exists on without another pass. For example,
List.map (fun x -> x.Length) ["one"; "two"] // this fails to compile
This is one of the reasons why the pipe operator is so useful, because it allows you to avoid type annotations:
["one"; "two"] |> List.map (fun x -> x.Length) // works
List.map (fun (x:string) -> x.Length) ["one"; "two"] //also works
The short answer:
The extension method ToDictionary is defined like this:
static member ToDictionary<'TSource,_,_>(source,_,_)
but is called like this:
source.ToDictionary<'TSource,_,_>(_,_)
The long answer:
This is the F# type signature of the function you are calling from msdn.
static member ToDictionary<'TSource, 'TKey, 'TElement> :
source:IEnumerable<'TSource> *
keySelector:Func<'TSource, 'TKey> *
elementSelector:Func<'TSource, 'TElement> -> Dictionary<'TKey, 'TElement>
But I only specified two regular parameters: keySelector and elementSelector. How come this has a source parameter?!
The source parameter is actually not put in the parenthesis, but is passed in by saying x.ToDictionary, where x is the source parameter. This is actually an example of a type extension. These kinds of methods are very natural in a functional programming language like F#, but more uncommon in an object oriented language like C#, so if you're coming from the C# world, it will be pretty confusing. Anyway, if we look at the C# header, it is a little easier to understand what is going on:
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector
)
So the method is defined with a "this" prefix on a first parameter even though it is technically static. It basically allows you to add methods to already defined classes without re-compiling or extending them. This is called prototyping. It's kinda rare if you're a C# programmer, but languages like python and javascript force you to be aware of this. Take this example from https://docs.python.org/3/tutorial/classes.html:
class Dog:
tricks = [] # mistaken use of a class variable
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick)
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks # unexpectedly shared by all dogs
['roll over', 'play dead']
The method add_trick is defined with self as a first parameter, but the function is called as d.add_trick('roll over'). F# actually does this naturally as well, but in a way that mimics the way the function is called. When you declare:
member x.doSomething() = ...
or
member this.doSomething() = ...
Here, you are adding function doSomething to the prototype (or class definition) of "x"/"this". Thus, in your example, you actually have three type parameters, and three regular parameters, but one of them is not used in the call. All you have left is to declare the key selector function, and the element selector function, which you did. That's why it looks weird.

Calling functions within case pattern matching is illegal pattern?

-module(erltoy).
-compile(export_all).
isFive(5) -> true;
isFive(_) -> false.
foo(X) ->
case X of
isFive(X) -> true;
3 -> false;
_ -> nope
end.
1> c(erltoy).
erltoy.erl:9: illegal pattern
error
Can I not call functions as part of the pattern match?
isFive(X) -> true; contains expression's which can't be computed to a constant at compile time and thus is not a valid pattern as a result. An arithmetic expression can be used within a pattern if it meets both of the following two conditions:
It uses only numeric or bitwise operators.
Its value can be evaluated to a constant when complied.
See this Example from the Erlang reference manual
case {Value, Result} of
{?THRESHOLD+1, ok} -> ...
to complete #byaruhaf answer, the left part of a case clause doesn't need to be a constant when compiled. the following code is valid, and obviously, Temp is not known at compile time (but foo(5) evaluates to nope!).
-module(erltoy).
-compile(export_all).
isFive(5) -> true;
isFive(_) -> false.
foo(X) ->
Temp = isFive(X),
case X of
Temp -> true;
3 -> false;
_ -> nope
end.
It is even not necessary that the left part is bound at execution time, for example, this is also valid, and there I is unbound before the case evaluation, and bound during the pattern matching:
get_second_element_of_3_terms_tuple_if_pos_integer(X) ->
case X of
{_,I,_} when is_integer(I), I>0 -> {true,I};
_ -> false
end.
The left part of a case must be a valid pattern with an optional guard sequence.
A valid pattern is an erlang term that may contains unbound variables, it may also contain arithmetic expressions if they respect the 2 conditions
It uses only numeric or bitwise operators.
Its value can be evaluated to a constant when complied.
the definition of a guard sequence is given there in erlang documentation
A final remark, the usual erlang way to code the kind of test function given in your example is to use different function heads, just as you do for isFive/1 definition.

OCaml functions passing in one less argument

I'm looking at solutions for a homework and the code implements an OCaml function that takes in two arguments but when its called, it's only passed one argument.
let rec func2 r x = match r with
| [] -> []
| (nt,rhs)::t -> if nt = x then rhs::(func2 t x) else func2 t x;;
let func1 r = fun x -> func2 r x;;
I would be calling func1 on a grammar rule like below by calling ( func1 awksub_rules )
let awksub_rules = [
Expr, [T"("; N Expr; T")"];
Expr, [N Num];
Num, [T"0"];
Num, [T"1"]
]
Expr and Num are just nonterminal types already defined and the T symbol means a terminal type.
I'm confused because func1 only takes in awksub_rules as an argument but the function declaration has two functions.
The intended output would be
function
| Expr -> [[T"("; N Expr; T")"]; [N Num]]
| Num -> [[T"0"]; [T"1"]]
I can see that func1 correctly returns a function and that func2 handles checking whether the left hand side (Expr or Num) is the same so it can concatenate to the list. But I have no idea what is passed into x.
When func1 is called with one argument, it returns another function, let's call it func3:
let func3 = func1 awksub_rules
At this point, there is no argument x yet. This new function still expects this argument to be passed in.
When you call this new function, you will pass in the value of x, and the computation will commence:
let result = func3 Num
I also would like to point out that func1 and func2 are logically equivalent because of the mechanism in ML called "partial application". That is, you can use func2 everywhere you use func1, and with same effect:
let func3 = func2 awksub_rules
let result = func3 Num
Fyodor Soikin's answer explains why func1 and func2 are logically the same. However, I don't want you to come away from this thinking that there is some magical language feature called "partial application". To stretch your mind, you need to understand how this arises from how functions work in OCaml.
In the ML languages, there is no such thing as a "function that takes in two arguments". Every function in ML takes exactly one argument (not zero, not two, not three; always one). The OCaml syntax
let rec func2 r x = ...
is syntactic sugar for
let rec func2 = function r -> function x -> ...
i.e. it is simply a definition of a function that returns another function. That's why the type of the function will be something like a -> b -> c (-> is right-associative, so that is the same as a -> (b -> c)) -- it says that it's a function that takes an a, and returns a function of type b -> c.
When you go to apply this function, what you think of as passing in two arguments, like func2 foo bar, is actually (because function application is left-associative) (func2 foo) bar, i.e. it is first applying func2 to the expression foo, and the result of that, a function, will then be applied to the expression bar.
The practice of taking in "multiple arguments" by taking in one argument and returning a function that takes another argument, etc. is called "currying". OCaml and other ML languages provide convenient syntax for defining curried functions (as you can see above, the common syntax let in OCaml allows you to define curried functions simply as listing the parameters next to each other), whereas in other languages, writing curried functions would require more verbose syntax. It's so convenient that, most of the time, we forget about it and think of it as multiple arguments. But it's always important to remember what it really means.
(Note that the OCaml compiler may or may not optimize curried functions into machine code functions that take multiple arguments, but that's an implementation detail that you shouldn't care about at the language level.)

Trying to get bind working for combination of State and Delayed monad

If the answer to this is "you are going about it all wrong", by all means let me know a more proper way. I had code which was structured like this:
type Res<'T> =
| E of (DC -> 'T)
| V of 'T
Now this type was primarily used directly, with a lot of inline code that did manual per-case binding, which is a lot of boilerplate I am trying to get rid of, so I figured I turn it into a computation expression. It wasn't too hard to get map, bind and apply right.
State was carried along through DC but this was cumbersome to get right, so I changed it to the following, which is a common signature I see in discussions with the state monad.
type Res<'T> =
| E of (DC -> DC * 'T)
| V of 'T
Then I decided to take it to the next level and introduce the Delayed monad (or Eventually or whatever its name is). So I changed my type as follows, making it recursive:
type Res<'T> =
| E of (DC -> DC * Res<'T>)
| V of 'T
I tried some variants of the following, but keep getting:
The resulting type would be infinite when unifying ''a' and 'Res<'a> -> Res<'b>'
(usually happens when I do not invoke the return, i.e. the Res.E <| below)
Or I can't seem to get my types right, the following (understandably) throws a type error, but I'm having a blind spot fixing it:
This expression was expected to have type 'Res<'a>' but here has type 'DC * Res<'a>'.
let rec bind k res =
match res with
| Res.V v -> k v // not delayed, should it be?
| Res.E e ->
Res.E <| fun dc -> bind k (e dc) // here's my error, on 'e dc'
//(fun dc -> dc, bind f (e dc))
bind k res
I understand that the signature should be ('a -> Res<'b>) -> Res<'a> -> XRes<'b>. The problem comes from getting the recursion right, at least in my head. I'm not even sure why I am feeding the result to Res.E, as in my understanding, the k continuation should already return this type anyway.
Also, I currently have the return as follows (following Steve Horsfield):
let result v = Res.V v
But also noticed in some posts (notably the hilarious Frankenfunctor) this:
let result v = Res.E <| fun dc -> dc, Res.V v
Maybe I am following a pattern I shouldn't have, but it seemed a good idea at the time, especially in trying to refactor zillions of boilerplate code and replace it with computation expressions, but perhaps I should stick to the direct evaluation, it fit in my head ;).
But I feel like I'm close... Any ideas?
I'm not quite sure what the meaning of this monad would be, but
Ok, after thinking about it a bit and reading the question's header :- ), I do understand what it means, and I can see how to build bind for it.
Your mistake is that the function wrapped in Res.E should return a tuple, but you're having it return just Res<'b> by recursively calling bind. And to mirror that, you're passing the result of e to recursive bind call in place of Res<'b> parameter, while e actually returns a tuple.
To do this correctly, you need to destructure the result of e, then pass second part to recursive bind call, and pair its result with the first part:
let rec bind (k: 'a -> 'b Res) (res: 'a Res) : 'b Res =
match res with
| V a -> k a
| E e ->
E <| fun dc ->
let dc', res' = e dc
dc', bind k res'
The terminal case, I don't believe should be also delayed. That is, I don't see a reason for it. As far as I understand, the interpretation of the V x case should be "a computation that doesn't change state and returns x", in which case making it delayed doesn't add anything but an extra lambda-expression.

How to read in an Int and use it in another function

I am trying to read in an Int and then use the read value in a pure function, but it does not seem to work properly. After searching through a lot of resources I use the from here.
So my code goes as the following:
main = do
putStrLn "Please input a number."
inputjar <- getLine
return (read inputjar :: Int)
Which works fine, but when I want to use it in my pure function:
usrSetBrick :: [[Int]] -> [[Int]]
usrSetBrick xs = setBrick (main) (main) (main) xs
I get a compile error:
Couldn't match expected type `Int' with actual type `IO Int'
In the first argument of `setBrick', namely `(main)'
In the expression: setBrick (main) (main) (main) xs
In an equation for `usrSetBrick':
usrSetBrick xs = setBrick (tull) (tull) (tull) xs
Failed, modules loaded: none.
So from what I understand does main return an int. Even it should, as I can understand from
return (read inputjar :: Int)
How can I make the read input usable in my function?
You probably don't want to be using main to return things since it's the entry point to your program. Instead, you can write a function
getInt :: IO Int
getInt = do
input <- getLine
return (read input) -- Don't have to specify Int here, GHC can figure it out from the type signature
However, your function setBrick, which presumably has the type Int -> Int -> Int -> [[Int]] -> [[Int]], can't use getInt directly. This is by design, Haskell's type system forces you to treat IO actions separately from pure functions (once you get used to it, it's a wonderful tool for reasoning about your code). Instead, you can do something like
promptInt :: IO Int
promptInt = do
putStrLn "Please input a number."
getInt
usrSetBrick :: [[Int]] -> IO [[Int]]
usrSetBrick xs = do
a <- promptInt
b <- promptInt
c <- promptInt
return $ setBrick a b c xs
The types Int and IO Int are not the same in Haskell, you can not use the interchangeably. This holds true for types like [Int], Maybe Int, and Either String Int as well, none of these the same as Int. Since main is an IO function, it doesn't return Int, it returns IO Int. In fact, return is not a special construct in Haskell at all, it's just a normal function that happens to wrap a value in a Monad. In this case, the Monad being used is IO, so return (read inputjar :: Int) has the type IO Int.
To expand on #Zeta's comment below, Haskell's return is not special and more importantly does not exit functions early. The following code will demonstrate this:
doSomething :: IO Int
doSomething = do
return "Test" -- Wouldn't type-check if this exited early
return 123 -- Would type check, but is ignored
putStrLn "You'll see this line printed"
return () -- Doesn't affect anything
x <- getLine -- Still happens
return 5678
putStrLn "Your input is meaningless! Here's a 0"
return ([1, 2], "hello", "world")
return 0 -- This is the actual return value
All those extra returns do nothing in Haskell (at least in the IO monad). All that happens is a value is wrapped in a constructor and chained together with the rest of the statements in that function. There are even some people in the Haskell community that view return as both unnecessary and confusing. Technically, return is equivalent to pure for Applicatives, and all Monads are also Applicatives, so it's not really providing us anything. At some point in the distant future, it's possible that the return function might disappear entirely, being completely superseded by pure. Again, neither of these functions are part of Haskell syntax, they're defined in the core libraries as plain, normal functions.

Resources