2016-08-15 3 views
2

Недавно я заметил, что я довольно часто пишу функции, которые просто итерацию другой функции f, пока она не достигнет фиксированной точки (например, что f x == x)В Haskell есть оператор с фиксированной точкой?

Я думал, что это довольно общее понятие, так что я думаю, что может быть построен в .

Так что мне было интересно, есть ли встроенный для этого или что-то более общее?

Так что я в основном ищу это:

fixedpoint f x= head . dropWhile(\y->y /= f y) $ iterate f x 

Я просто имел проблемы прибегая к помощи этого, потому что я нашел только ссылки на функции fix всякий раз, когда мой срок поиска содержал fixed point или что-то подобное.

+0

@vikingsteve Насколько я знаю, это просто дополнение к 'dropWhile', но я не вижу, как это позволяет найти неподвижные точки? – flawr

+0

Хорошо, я из моей глубины здесь. Была просто мысль :) – vikingsteve

+0

Я по-прежнему ценю ваши усилия =) – flawr

ответ

1

У вашей функции есть подпись Eq a => (a -> a) -> a -> a.

Using hoogle to search for that, я не вижу точных совпадений. Ближайший матч until

until :: (a -> Bool) -> (a -> a) -> a -> a

база Прелюдия

until p f дает результат не применяя f до p держит.

Вы, вероятно, может использовать, чтобы написать функцию, но потому, что вам нужно /= вам нужно Eq ограничение.

+0

Вы можете использовать 'до' с парами, но я думаю, что проще всего сделать все это вручную. – dfeuer

+0

или 'last. takeWhileDifferent. итерация f' или аналогичная запись own 'last. takeWhileDifferent' variant ... takeWhileDifferent = https://github.com/ekmett/ad/blob/ac5e0c7091430d0c569ba893f78385ead70b918e/src/Numeric/AD/Internal/Combinators.hs#L51 – phadej

4

Просто напишите сами. Прямая версия будет быстрее, чем одна, используя dropWhile.

hammer :: Eq a => (a -> a) -> a -> a 
hammer f x 
    | x' == x = x' 
    | otherwise = hammer f x' 
    where x' = f x 
+0

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

+0

@flawr, я не думаю, что это особенно распространено, на самом деле. 'пока' кажется ближайшим, но на самом деле использовать его для этой цели больше проблем, чем это стоит. – dfeuer

1

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

until=<<((==)=<<) :: Eq a => (a -> a) -> a -> a 

Возможно, это выглядит немного странно, но на самом деле это просто точечный эквивалент until (\x -> f x == x) f, используя тот факт, что f (g x) x может быть выражен в (f=<<g) x дважды.

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