Как сделать (String, Int) из (String, ())? - PullRequest
0 голосов
/ 25 января 2019

Для упражнения на WriterMonads мне нужно создать функцию, которая регистрирует, что она делает Я не должен использовать конструктор кортежей (,).

У меня уже есть функция журнала с типом результата (String, ()) Теперь мне нужно использовать этот, но с типом результата (String, Int)

Но я не понимаю, как сделать (String, ()) кортеж для (String, Int)

logMsg :: String -> (String,())
logMsg  msg = (msg,()) -- Durch Lösung ersetzen.

logOp :: Int -> Int -> Int -> String -> (String,())
logOp v1 v2 res math = do
    logMsg "The value of "
    logMsg $ show v1
    logMsg  math
    logMsg $ show v2
    logMsg " is "
    logMsg $ show res
    logMsg ".\n"


mult :: Int -> Int -> (String,Int)
mult m1 m2 = logOp m1 m2 (m1*m2) "*"

Я проверял это

logOp m1 m2 (m1*m2) "*"

делает правильный результат типа (String, ())

Понятия не имею, есть намеки?

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Обычно при работе с монадами используются монадические функции return и (>>=). Вы уже неявно используете (>>=) в своем блоке do.

Для mult, вы можете попробовать использовать do и использовать return внутри него. В этом очень специфическом случае вы можете предположить, что return определяется как

return :: Int -> (String, Int)
return x = ("", x)

(В общем случае, он полиморфен: return :: a -> (String, a))

0 голосов
/ 25 января 2019

Я не смог найти метод, который напрямую обновляет значения в кортеже без использования конструктора, поэтому мне пришлось написать его неэффективным способом. Но этот не использует конструктор кортежей:

mult m1 m2 = head $ zip [fst $ logOp m1 m2 (m1*m2) "*"] [m1*m2]

Таким образом, функция zip создает список кортежей из двух списков, а затем, используя функцию head, мы извлекаем первый элемент как кортеж, а функция fst извлекает строку String из (String, ()) пары. .

...