[Haskell] проверка на _|_
От: nikov США http://www.linkedin.com/in/nikov
Дата: 18.05.09 13:36
Оценка:
Как на Haskell написать функцию :: [a] -> (), которая равна (), если список пуст или хотя бы одно значение из списка не _|_, и _|_ в противном случае?
На машине Тьюринга такое сделать можно.
Re: [Haskell] проверка на _|_
От: thesz Россия http://thesz.livejournal.com
Дата: 18.05.09 13:47
Оценка:
N>Как на Haskell написать функцию :: [a] -> (), которая равна (), если список пуст или хотя бы одно значение из списка не _|_, и _|_ в противном случае?
N>На машине Тьюринга такое сделать можно.

*MainLayout> foldr seq () [1,error "aaa"]
*** Exception: aaa
*MainLayout> foldr seq () [1,2]
()
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re: [Haskell] проверка на _|_
От: deniok Россия  
Дата: 18.05.09 13:58
Оценка:
Здравствуйте, nikov, Вы писали:

N>Как на Haskell написать функцию :: [a] -> (), которая равна (), если список пуст или хотя бы одно значение из списка не _|_, и _|_ в противном случае?

N>На машине Тьюринга такое сделать можно.

Под _|_ понимается бесконечное вычисление? То есть явный undefined мы выкидываем?

Если так, то можно, например, сделать шедулер-запускальщик вычислений, типа описанного здесь в конце раздела 9.3
Автор(ы): Пол Хьюдак, Джон Петерсон, Джозеф Фасел
Дата: 24.04.2007
Данный материал – продолжение начатого в прошлом номере введения в программирование на Haskell для имеющих опыт программирования, по крайней мере, на одном языке, желательно функциональном (даже если это «почти функциональный» язык, такой как ML или Scheme).
и использовать его, запуская

1ый шаг над 1ым элементом ->
1ый шаг над 2ым элементом -> 2ой шаг над 1ым элементом ->
1ый шаг над 3им элементом -> 2ой шаг над 2ым элементом -> 3ий шаг над 1ым элементом ->
...

При этом если какой-то шаг заканчивает какое-то вычисление — функция тут же возвращает ().
Re[2]: [Haskell] проверка на _|_
От: Курилка Россия http://kirya.narod.ru/
Дата: 18.05.09 14:07
Оценка:
Здравствуйте, thesz, Вы писали:

N>>Как на Haskell написать функцию :: [a] -> (), которая равна (), если список пуст или хотя бы одно значение из списка не _|_, и _|_ в противном случае?

N>>На машине Тьюринга такое сделать можно.

T>
T>*MainLayout> foldr seq () [1,error "aaa"]
T>*** Exception: aaa
T>*MainLayout> foldr seq () [1,2]
T>()
T>


в 1-м случае мы же () должны получить?
Re: [Haskell] проверка на _|_
От: Курилка Россия http://kirya.narod.ru/
Дата: 18.05.09 14:08
Оценка:
Здравствуйте, nikov, Вы писали:

N>Как на Haskell написать функцию :: [a] -> (), которая равна (), если список пуст или хотя бы одно значение из списка не _|_, и _|_ в противном случае?

N>На машине Тьюринга такое сделать можно.

А для МТ приведи алгоритм?
Re[3]: [Haskell] проверка на _|_
От: thesz Россия http://thesz.livejournal.com
Дата: 18.05.09 14:15
Оценка: +1
N>>>Как на Haskell написать функцию :: [a] -> (), которая равна (), если список пуст или хотя бы одно значение из списка не _|_, и _|_ в противном случае?
N>>>На машине Тьюринга такое сделать можно.
T>>
T>>*MainLayout> foldr seq () [1,error "aaa"]
T>>*** Exception: aaa
T>>*MainLayout> foldr seq () [1,2]
T>>()
T>>


К>в 1-м случае мы же () должны получить?


Mea culpa, недосмотрел.

Пусть мне покажут, как проверить невычислимость на машине Тьюринга, тогда я сделаю и на ФЯ.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re: [Haskell] проверка на _|_
От: palm mute  
Дата: 18.05.09 16:04
Оценка: 45 (2)
Здравствуйте, nikov, Вы писали:

N>Как на Haskell написать функцию :: [a] -> (), которая равна (), если список пуст или хотя бы одно значение из списка не _|_, и _|_ в противном случае?

N>На машине Тьюринга такое сделать можно.

По-нормальному — никак (кстати, зачем это нужно?).
По-извращенски — есть http://haskell.org/haskellwiki/Unamb:
import Data.Unamb
main = print foldr1 unamb $ map (\x -> x `seq` ()) [error "a", error "b", 42]


Учтите, там внутри запускаются потоки и довольно-таки нестандартным образом обрабатываются исключения; кроме того, unamb имеет предусловие, нарушение которого ломает ссылочную прозрачность.
Re: [Haskell] проверка на _|_
От: vshabanov http://vshabanov-ru.blogspot.com
Дата: 18.05.09 18:38
Оценка: +1
Здравствуйте, nikov, Вы писали:

N>Как на Haskell написать функцию :: [a] -> (), которая равна (), если список пуст или хотя бы одно значение из списка не _|_, и _|_ в противном случае?

N>На машине Тьюринга такое сделать можно.

А что есть _|_ на машине тьюринга?

Какой _|_ на хаскеле, вечный цикл или undefined?

А так, запусти процессы, делающие putMVar после успешного seq и жди этой MVar. Собственно unamb делает примерно это.
Re[2]: [Haskell] проверка на _|_
От: nikov США http://www.linkedin.com/in/nikov
Дата: 18.05.09 18:54
Оценка:
Здравствуйте, palm mute, Вы писали:

PM>По-извращенски — есть http://haskell.org/haskellwiki/Unamb


Да, именно это искал. Спасибо.
Re[4]: [Haskell] проверка на _|_
От: nikov США http://www.linkedin.com/in/nikov
Дата: 18.05.09 18:58
Оценка:
Здравствуйте, thesz, Вы писали:

T>Пусть мне покажут, как проверить невычислимость на машине Тьюринга, тогда я сделаю и на ФЯ.


Проверить невычислимость нельзя, но благодаря наличию универсальной машины можно запустить несколько вычислений параллельно, и ждать остановки хотя бы одного из них.
Re[5]: [Haskell] проверка на _|_
От: thesz Россия http://thesz.livejournal.com
Дата: 18.05.09 21:07
Оценка:
T>>Пусть мне покажут, как проверить невычислимость на машине Тьюринга, тогда я сделаю и на ФЯ.
N>Проверить невычислимость нельзя, но благодаря наличию универсальной машины можно запустить несколько вычислений параллельно, и ждать остановки хотя бы одного из них.

Bottom это не только "нет остановки". Точнее, это самый неинтересный случай.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[5]: [Haskell] проверка на _|_
От: thesz Россия http://thesz.livejournal.com
Дата: 18.05.09 21:30
Оценка:
T>>Пусть мне покажут, как проверить невычислимость на машине Тьюринга, тогда я сделаю и на ФЯ.

N>Проверить невычислимость нельзя, но благодаря наличию универсальной машины можно запустить несколько вычислений параллельно, и ждать остановки хотя бы одного из них.


import Control.Parallel

notABot [] = ()
notABot (x:xs) = (x `pseq` ()) `par` notABot xs

loop = loop

result = 2

test = notABot [loop,result]

main = do
    print test
    putStrLn "Hi!"


Удовлетворительно ль?

А теперь говори, как ты собрался пользоваться результатами работы этой функции?
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[6]: [Haskell] проверка на _|_
От: VoidEx  
Дата: 18.05.09 21:38
Оценка:
Здравствуйте, thesz, Вы писали:

T>Удовлетворительно ль?

Не очень
test = notABot [loop, loop]
Re: [Haskell] проверка на _|_
От: VoidEx  
Дата: 18.05.09 21:54
Оценка:
Здравствуйте, nikov, Вы писали:

N>Как на Haskell написать функцию :: [a] -> (), которая равна (), если список пуст или хотя бы одно значение из списка не _|_, и _|_ в противном случае?

N>На машине Тьюринга такое сделать можно.
import Control.Concurrent
import Control.Exception
import System.IO.Unsafe

notABot [] = return ()
notABot xs = do
  qsem <- newQSem 0
  ths <- mapM (\t -> forkIO $ (evaluate t >> signalQSem qsem)) xs
  waitQSem qsem
  mapM_ killTheads rhs
  return ()

checkBottom = unsafePerformIO . notABot

В данном случае чистота функции checkBottom лежит на моей ответственности. Т.е. при bottom она выдаёт bottom, а в остальных случаях всегда одно и то же значение. Так что IO там только для деталей реализации.
Собственно, в unamb что-то типа этого и сделано.
Re[6]: [Haskell] проверка на _|_
От: nikov США http://www.linkedin.com/in/nikov
Дата: 19.05.09 10:12
Оценка:
Здравствуйте, thesz, Вы писали:

T>А теперь говори, как ты собрался пользоваться результатами работы этой функции?


Тут главным образом теоретический интерес.
Re[6]: [Haskell] проверка на _|_
От: nikov США http://www.linkedin.com/in/nikov
Дата: 19.05.09 10:14
Оценка:
Здравствуйте, thesz, Вы писали:

T>Bottom это не только "нет остановки". Точнее, это самый неинтересный случай.


А какие еще? Вроде бы только ошибка, но ее перехват, в отличие от незавершающегося вычисления, не представляется затруднительным.
Re[7]: [Haskell] проверка на _|_
От: Курилка Россия http://kirya.narod.ru/
Дата: 19.05.09 10:50
Оценка:
Здравствуйте, nikov, Вы писали:

N>Здравствуйте, thesz, Вы писали:


T>>Bottom это не только "нет остановки". Точнее, это самый неинтересный случай.


N>А какие еще? Вроде бы только ошибка, но ее перехват, в отличие от незавершающегося вычисления, не представляется затруднительным.


К примеру ядерная боеголовка, упавшая на твой дом тоже _|_
Как более приближенный к жизни вариант — вычисление с unsafePerfomIO в ходе которого получаем BSOD
Re[7]: [Haskell] проверка на _|_
От: thesz Россия http://thesz.livejournal.com
Дата: 19.05.09 17:10
Оценка:
T>>Bottom это не только "нет остановки". Точнее, это самый неинтересный случай.
N>А какие еще? Вроде бы только ошибка, но ее перехват, в отличие от незавершающегося вычисления, не представляется затруднительным.

И как ты это хочешь сделать?
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.