Как работать с метками в mozart oz, чтобы получить элементы из пары/кортежа?

Я новичок в Моцарте Оз, и мне нужно решить следующие проблемы:

  a) Implement a function Zip that takes a pair Xs#Ys of two lists Xs and Ys (of the
 same length) and returns a pairlist, where the first field of each pair is taken
 from Xs and the second from Ys. For example, {Zip [a b c]#[1 2 3]} returns the
 pairlist [a#1 b#2 c#3].

  b) The function UnZip does the inverse, for example {UnZip [a#1 b#2 c#3]}
 returns [a b c]#[1 2 3]. Give a specification and implementation of UnZip.

Все, что я знаю, это то, что # — это своего рода метка, которая составляет пару/кортеж, взятую из документации, но я не смог найти пример, иллюстрирующий, как с ней работать.

Мой вопрос заключается в том, как разделить его, чтобы получить элементы или как работать с этим ярлыком (или любым источником, в котором может быть пример того, как с ним работать).

Я немного поискал и пришел к этому фрагменту кода (я не знаю, правильно ли он вообще синтаксически):


    declare
    fun {Zip L}
       case L of nil then nil
       [] L1#L2 then .... % Here i'm stuck or i don't know how to proceed
       end
    end

    {Browse {Zip ['a' 'b' 'c']#[1 2 3]}}

Любая помощь будет оценена.

Спасибо за ваше время.


person Cipri    schedule 23.11.2019    source источник


Ответы (2)


По сути, сопоставление с образцом в стране Оз — один из самых мощных инструментов. Мы не можем использовать циклы for, так как переменные неизменяемы, поэтому мы используем рекурсию.

functor
import
    System
    Application
define
    fun {Zip L}
      case L of L1#L2 then
        case L1 of H1|R1 then
          case L2 of H2|R2 then
            H1#H2|{Zip R1#R2}
          else nil end
        else nil end
      else nil end
    end
    {System.show {Zip ['a' 'b' 'c']#[1 2 3]}} 

    % Shows [a#1 b#2 c#3]

    {Application.exit 0}
end
person Elias Vågan    schedule 27.11.2019
comment
Как этот код решает описанную проблему? Пожалуйста, дополните - person Orestis Zekai; 27.11.2019
comment
спасибо, первое требование решено, но теперь я застрял в функции UnZip. Можете подсказать как решить? Спасибо :) - person Cipri; 08.12.2019
comment
Мне удалось сделать это declare fun {UnZip L S F} case L of nil then S#F [] H|T then case H of H1#H2 then {UnZip T H1|S H2|F} else nil end end end {Browse {UnZip [a#1 b#2 c#3] nil nil}} % Shows [c b a]#[3 2 1] % Should show [a b c]#[1 2 3], но он возвращает списки в обратном порядке, какие-либо предложения, чтобы он отображался правильно? - person Cipri; 08.12.2019

Все, что вам нужно, это функция, которая переворачивает списки:

    declare
    fun {ReverseAux L1 L2}
       case L1
       of nil then L2
       [] H|T then {ReverseAux T H|L2}
       end
    end
    
    
    % wrapper for reverse
    
    declare
    fun {Reverse L}
       {ReverseAux L nil}
    end
    
    

Тогда ваша функция UnZip может быть написана так:

    declare
    fun {UnZipAux L S D}
       case L
       of nil then {Reverse S}#{Reverse D}
       [] X#Y|T then {UnZipAux T X|S Y|D}
       end
    end

    
    % wrapper for UnZip

    declare
    fun {UnZip L}
       {UnZipAux L nil nil}
    end

Надеюсь, ты хорошо справился, братан, теперь это и моя домашняя работа :))

person Arrriba    schedule 23.11.2020