ML: соответствие неполным

Я хочу создать функцию с именем headcol, которая работает так:

headcol[[1,2],[3,4]] = [1,3]; 

Итак, я сделал такую ​​функцию:

fun headcol [] = [] 
  | headcol [x::xs',y::ys'] = [x,y]

но когда я это называю, я получаю совпадение неисчерпывающим.

Я хочу сделать функцию с именем 'headcol', вы должны уточнить, чего вы действительно хотите. Ваш параметр - это список (который может иметь бесконечное количество элементов), но вы только математический список из двух элементов. Вот что означает nonexhaustive
Chen Li 01.11.2018 05:00
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
581
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

IIUC, headcol извлечет все заголовки списков в параметре, тип которого - 'a-list-list. То, что вы математикаете, - это только [] и [x::xs', y::ys'], и ничего больше. Итак, если ваш аргумент имеет более двух подсписок, выполнение вызовет:

- headcol[[1,2],[3,4], [4, 5, 9]]; 

uncaught exception Match [nonexhaustive match failure]
  raised at: a.sml:9.34
- 

Если вы просто хотите иметь дело со списком из двух элементов, пара - лучший выбор. В противном случае вам следует сопоставить больше случаев:

fun headcol list =
    case list of
        [] => []
      | x::xs' =>
        case x of
            [] => headcol xs'
         |  h::t => h::(headcol xs')

выход:

- headcol[[1,2],[3,4], [4, 5, 9]]; 
- val it = [1,3,4] : int list

Не могли бы вы переписать функцию, используя «карту»?

zion 02.11.2018 06:13

@ 이시온 Саймон дал исчерпывающую и идеальную демонстрацию map. Если где-то вы чего-то не понимаете, не стесняйтесь указать на это.

Chen Li 02.11.2018 06:56

Как указывает 陳 力, трудно ответить на вопрос, определяемый только именем функции и попыткой ее решения. Тем не менее, head звучит так, как будто вы хотите взять первый элемент каждого подсписка, а col звучит так, как будто вы обрабатываете этот список списков как матрицу со столбцами, ортогональными к подспискам.

Рекурсивное решение также может выглядеть так:

fun headcol [] = []
  | headcol ((x::_)::xss) = x :: headcol xss
  | headcol ([]::xss) = headcol xss

Вот как это можно сделать, используя встроенные комбинаторы списков более высокого порядка:

fun headcol xss =
    List.concat (List.map (fn xs => List.take (xs, 1)) xss)

Причина, по которой я не просто делаю:

fun headcol xss =
    List.map hd xss

потому что hd является частичной функцией, поэтому hd [] выйдет из строя во время выполнения.

С другой стороны, List.take ([], 1) вернет [].

И List.concat объединит временный результат [[1],[2],[3]] в [1,2,3].

Или, если столбец отсутствует, [[1],[],[3]] в [1,3].

Тестовые примеры:

val test_headcol_0 = headcol [] = []
val test_headcol_1 = headcol [[1]] = [1]
val test_headcol_2 = headcol [[1,2],[3,4]] = [1,3]
val test_headcol_3 = headcol [[1,2,3],[4,5,6],[7,8,9]] = [1,4,7]
val test_headcol_4 = headcol [[1],[2,3],[4,5,6]] = [1,2,4]
val test_headcol_5 = headcol [[1],[],[2,3]] = [1,2]

Конечно, я не знаю, ожидаете ли вы от headcol такого поведения в отношении нерегулярных матриц, у которых нет столбца заголовка. Это угловой случай, в который вы не входите. В функциональном программировании вы часто встраиваете обработку ошибок в возвращаемое значение, а не генерируете исключения.

Так, например, вы можете захотеть, чтобы от headcol возвращался 'a list option, где SOME [1,4,7] предполагает, что каждая строка действительно имеет столбец заголовка, а NONE предполагает, что по крайней мере одна строка не смогла создать столбец.

Или вы можете использовать тип данных, отличный от 'a list list, для представления вашей матрицы, которая не допускает строк с отсутствующими столбцами, например. Массив2.

Другие вопросы по теме