[m-users.] Question about strings

Richard O'Keefe raoknz at gmail.com
Wed Apr 4 22:40:13 AEST 2018


​​
"mod it by 5" isn't English.  It uses English words, but it's not English.
"Take its remainder modulo 5" is probably what you're after.

Let's see what this looks like in a functional language (SML).

(* repeat(string, count) returns a new string that is the
   concatenation of (count) copies of (string).
   Note that x ^ y is the concatenation of two strings, x and y.
*)
fun repeat (string, count) =
   if count >= 2 then
      repeat(string, count div 2) ^ repeat(string, count - count div 2)
   else if count = 1 then string else "";

(* answer(string, number) solves the problem, except for
   input and output.
*)
fun answer (string, number) = repeat(string, number mod 5);

Now the interesting thing here is that Mercury lets you write
functions *as* functions, not just as predicates with an
extra argument.

To do arithmetic, you'll have to
:- import_module int.
and then you get mod, >=, div, - and so on without writing
any functions or predicates of your own.
To do string concatenation, you'll have to
:- import_module string.
and then you can use append(X, Y) or the nicer X ++ Y.

:- func repeat(string, int) = string.

repeat(s, n) =
    (if n >= 2 then repeat(s, n div 2) ++ repeat(s, n - n div 2) else
        (if n = 1 then s else "")).

:- func answer(string, int) = string.

answer(s, n) =
    repeat(s, n mod 5).

The string module also provides string.det_to_string(str) which
converts a string to an integer or raises an exception if it is
not an integer representation.

Now, what about reading and writing?
Well, the Wikipedia page about Mercury has an example.
Hint: you will need

:- import_module io.

main(!IO) :-
    ....




On 2 April 2018 at 15:17, Charles Shuller <charles.shuller at gmail.com> wrote:

> Solving problems in languages like mercury is somewhat different than in
> C-like langues.
>
> In a C-type language, and especially in Object Oriented Languages, you
> address a problem with:
>
> State:  Stuff I'm going to use to compute things with
> Functions:  Little (hopefully) chunks of steps I need to do to compute the
> answer
> Basic Algorithm:
>     Fill up the state
>     Change the state with the functions until you have the answer
>
> Here is a quick example:
>
> int sum_array(int* array) {
>    /** Initialize the state */
>    int i = 0;
>    int total = 0;
>    int array_length = length(array);
>
>    /** Alter the state until we have the answer */
>    for(i = 0; i < array_length; i++) {
>       total = total + array[i];
>    }
>
>   /** Return the answer */
>   return total.
> }
>
>
> In functional programming, things are more like this:
>
> State:  Doesn't Exist.  You'll probably try to habitually create some,
> just delete it.   Everything is in the parameters and a few intermediate
> vars that don't change ever.
> Functions:  Relations (i.e. how the parameters are related), NOT a chunk
> of steps
> Basic Algorithm:  There isn't one, it's all just a relation.
>
> Yep, the explanation above is totally worthless when your starting out,
> and the more experianced guys can probably make it a heck of a lot more
> accurate, but that's the best way I can explain it concisely.   Here is a
> similar example in mercury-ish (it's late and I don't have a compiler on
> hand to give you a proper example right now):
>
> **If you want a loop, you can cheat by recursing, but in a functional
> language this often means there is a nicer solution to be found by thinking
> about things a differently.   Though your assignment was likely given with
> the explicit purpose of making you learn how to loop, so don't fret over
> this right now.
>
>
> :- func sum_list(list(int)) = int.
> sum_list([]) :- 0.  %% If the list is empty, return zero.
> sum_list([ListHead | ListTail]) :-
>    ListHead + sum_list(ListTail).   %%Return the first element in the list
> added to the sum of the rest of the list.  Here Tail refers to everything
> but the Head.
>
>
>
>
>
> So, for your programming assignment, the easiest way to go about things is
> to implement a main loop recursively, as something like:
>
>
>
> %%!IO here is a clever device that makes Input and Output look like normal
> parameters.  This is a lie, but think of it as already containing all the
> values the user will ever input, and messages that will ever be output.
> main_event_loop(!IO) :-
>    Var  = read_input(!IO),
>    handle_input(Var, !IO),
>    main_event_loop(!IO).  %%In many languages this will result in
> stack-space exhaustion, not in Mercury.
>
>
> And something similar for outputting to the screen.
>
> On a final note, your assignment is meant to be of a particular difficulty
> for imperative languages.   It is actually a bit more complicated to
> implement in a functional language because we have to write in a way that
> has no side-effects.  You have almost certainly already been taught to
> solve problems by loading up state, then modifying it repeatedly.
> Learning a different way to solve problems can be very challenging so
> please try not to feel too frustrated.
>
>
> Cheers!
>
> Charles
>
>
>
>
>
>
>
> On Sun, Apr 1, 2018 at 8:13 PM, Astrid Garcia <mellgarcia0397 at gmail.com>
> wrote:
>
>> One part of my project consists on taking as input a number and a string
>> from the user. Process the number and mod it with 5 and the result will be
>> the times I will duplicate the string that they input. I got the math part
>> correct, but I run into problems when I try to read and store the string
>> and to duplicate it. I am confused as to what is the equivalent on Mercury
>> of the Java  while loop, the "if (x == 1)" expression and the reading from
>> user like the "string = input.nextLine();" in Java
>>
>> Thank you for your help and time,
>>
>> Astrid Garcia
>>
>> On Sun, Apr 1, 2018 at 7:23 PM, Astrid Garcia <mellgarcia0397 at gmail.com>
>> wrote:
>>
>>> Hi,
>>>
>>> I would appreciate help regarding reading input and using it in
>>> functions. I am working on a program in which I need to read input, store
>>> it in a variable. How can I do this? and plus how can I declare a function
>>> that takes a string, a number as input and outputs another string. I
>>> created one for mod operation "pred modnum(int::in, int::out) is det." how
>>> would the other function be constructed if it's taking in an int a string
>>> and it will output a string?
>>>
>>> Thank you for your time,
>>>
>>> Astrid Garcia
>>>
>>
>>
>> _______________________________________________
>> users mailing list
>> users at lists.mercurylang.org
>> https://lists.mercurylang.org/listinfo/users
>>
>>
>
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org
> https://lists.mercurylang.org/listinfo/users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20180405/d5a60d93/attachment.html>


More information about the users mailing list