2015-11-09 2 views
1
within :: (Ord a, Num a) => a -> [a] -> a 

, который принимает толерантность, то есть число эпсилон и бесконечный список номеров, и смотрит вниз список, чтобы найти два последовательных числа в списке, которые отличаются не более чем эпсилон она возвращает второй из эти. (Это может никогда не вернуться, если нет такой пары последовательных элементов). Например,Как реализовать функцию внутри Haskell?

within 1.0 [1.0 ..] = 2.0 
within 0.5 ([1.0, 32.5, 17.2346, 10.474, 8.29219, 8.00515] 
++ [8.0, 8.0 ..]) 
= 8.00515 
+2

Итак ... Каков ваш вопрос? – Zeta

+0

На самом деле я не знаю, как взять 2 элемента за раз и проверить, отличаются ли они не более чем на epsilon. Если я напишу что-то вроде check xye = abs (xy) <= e, я действительно не знаю, как его использовать в письменной форме в функции – Alice

+2

Я не на своем компьютере, но я написал ответ о принятии двух элементов список ранее сегодня. Это может быть полезно. В основном используйте 'in eps (x: y: xs) = ...'. Однако вы должны думать о поведении функции, если список не бесконечен и/или не содержит фиктивную пару. – Zeta

ответ

5

В Haskell, список просто другая структура данных, возможно, с некоторыми (на мой взгляд) в заблуждение обозначения. С любой структурой данных вы можете использовать сопоставление шаблонов. Когда вы работаете со списками, у вас есть три возможные вещи по шаблону:

  • Переменная, например x.
  • Конструктор применяется к нулю или более моделей,
    • как с (:) x xs (или, возможно, более familiarily: x:xs)
    • или []

Обратите внимание, что в образцах, вы применить конструкторы к узоров. Совершенно допустимо писать (:) x ((:) y ys) (чаще всего записывается как x:y:ys), который соответствует любому списку из по меньшей мере двух элементов и присваивает первому элементу x, второй - y, а остальную часть списка - ys.

Скелет вашей within функции будет выглядеть примерно так:

theFunction theList = case theList of 
          x:y:ys -> if canGiveAnswer x y 
             then buildAnswer x y 
             else theFunction (y:ys) 

Здесь theFunction пытается сопоставить свой вклад с шаблоном x:y:ys, проверяет, является ли x и y достаточны, чтобы дать ответ, и сделать поэтому, когда это возможно, или перезапустить себя (theFunction (y:ys)) с удалением первого элемента списка.

Вы можете написать это более сжато, как

theFunction (x:y:ys) = if canGiveAnswer x y then buildAnswer x y else theFunction (y:ys) 

или даже

theFunction (x:y:ys) | canGiveAnswer x y = buildAnswer x y 
        | True = theFunction (y:ys) 

Конечно, в вашем случае, вам нужен дополнительный аргумент:

within :: (Ord a, Num a) => a -> [a] -> a 
within epsilon (x:y:ys) | canGiveAnswer x y epsilon = buildAnswer x y epsilon 
         | True = within epsilon (y:ys) 

Я буду оставьте это до вас, чтобы выяснить, что должно быть canGiveAnswer и buildAnswer.

+0

Спасибо! Это было очень полезно! : D – Alice

Смежные вопросы