Я использую эту функцию для чтения списка натуральных чисел из строки в следующем формате: [1, 2, 3]:

readMaybeIntList :: String -> Maybe [Int]
readMaybeIntList line = case readMaybe line of
                          Just l -> return l
                          Nothing -> Nothing

Прямо сейчас это работает только для целых чисел - какой будет правильный способ проверить, являются ли числа натуральными? Должен ли я изменить предложение Just l, чтобы проверить, все ли числа >=0? Является ли хорошей идеей вернуть Nothing из такого вложенного Just предложения?

1
syntagma 28 Май 2017 в 23:55

2 ответа

Лучший ответ

Что ж, если вы все равно собираетесь использовать return для вызова экземпляра монады для Maybe, тогда я думаю, что, вероятно, напишу:

import Text.Read
import Control.Monad

readMaybeNatList :: String -> Maybe [Int]
readMaybeNatList line = do
  ns <- readMaybe line
  guard $ all (>=0) ns
  return ns

Что является более идиоматическим применением монады Maybe. Является ли это более ясным, чем явная альтернатива сопоставления с образцом (и без монады):

readMaybeNatList' :: String -> Maybe [Int]
readMaybeNatList' line =
  case readMaybe line of
    Just ns | all (>=0) ns -> Just ns
    _ -> Nothing

Это, вероятно, вопрос мнения и предполагаемой аудитории.

1
K. A. Buhr 28 Май 2017 в 22:27

Вы можете использовать do - нотацию и guard из Control.Monad, чтобы избежать чрезмерного сопоставления с образцом:

import Text.Read
import Control.Monad


readMaybeNatural :: String -> Maybe Int
readMaybeNatural str = do
  n <- readMaybe str
  guard $ n >= 0
  return n


readMaybeNaturals :: String -> Maybe [Int]
readMaybeNaturals =
  sequence . map readMaybeNatural . words
1
Anler 28 Май 2017 в 21:56