nomyx / Nomyx

The Nomyx game
83 stars 9 forks source link

Lazy inputs #121

Open cdupont opened 8 years ago

cdupont commented 8 years ago

It would be interesting to manage infinite list of inputs. The idea would be to present the inputs one by one to the user, until they are interrupted.

cdupont commented 8 years ago

From Control.Applicative:

One or more:
some :: f a -> f [a]

Zero or more:
many :: f a -> f [a]

If defined, some and many should be the least solutions of the equations:
some v = (:) <$> v <*> many v
many v = some v <|> pure []

See http://stackoverflow.com/questions/7671009/functions-from-alternative-type-class/7681283#7681283

for Event:

One or more:
some :: Event a -> Event [a]

Zero or more:
many :: Event a -> Event [a]

If defined, some and many should be the least solutions of the equations:
some v = (:) <$> v <*> many v
many v = some v <|> pureEvent []
test :: Event [String]
test = some (inputText 1 "Enter text")

Would just produce an infinite quantity of text fields, without possibility to stop it. However with a form such as:

fields :: Event (Maybe String)
fields = Just <$> inputText 1 "Enter" <|> Nothing <$ inputButton finish"

It makes sense to repeatitively ask for the input, until the button "finish" is pressed: somes :: Event (Maybe [String]) somes = some fields

In this case the Functor is (Event Maybe).

cdupont commented 8 years ago

From Haskell mailing list:

I think this may have something to do with the default definition of many in the definition of Alternative:

many :: f a -> f [a]
many v = many_v
  where
    many_v = some_v <|> pure []
    some_v = (fmap (:) v) <*> many_v

many_v and some_v are mutually recursive functions, and it may be that this prevents the thunks from being made available to take in some way. I'm really not sure though, this is just an idea about why this is not quite the same as (take $ repeat 1)

The problem is that many is creating an infinite sum that’s nested to the left. So you’re trying to compute

(((… <|> Just [1,1,1]) <|> Just [1,1]) <|> Just [1]) <|> Just 1

which will never terminate because Maybe is strict in the first argument to <|>.

As a practical matter, the Alternative instance for Maybe should probably be changed to either call error or return Just (repeat v).

Similarly, we should probably flip the order for many in the instance for [].

So basically it would work only for repeat etc.