2016-02-20 3 views
0

В проекте я использую модуль, содержащий глобальные (константные однократно инициализированные) материалы, которые я использую в остальной части проекта. Я решил разместить их в модуле, чтобы избежать большого количества аргументов. Проблема в том, что этот модуль должен быть инициализирован во время выполнения с аргументом выполнения программы.Инициализация модуля в функциональной программировании

Как это можно сделать в функциональной парадигме, например, в языке Haskell?

Edit:

Чтобы быть более точным, я закодировать свой проект в императивном языке (Ada), поэтому я могу использовать модуль, содержащий переменные инициализированы во время выполнения, а затем использовать в качестве глобальных констант (с встроенный геттер). Однако, интересуясь функциональным программированием, мне интересно, как получить тот же результат в этой парадигме; Я хочу иметь световые сигнатуры на всем протяжении кода (используя глобальную константу), данные модуля, локализованные в секции данных памяти, даже иметь возможность инициализировать разные «константы» модуля отдельно и т. Д.

+4

хорошо вы читаете аргументы в 'main' с помощью' 'getArgs' '(https://hackage.haskell.org/package/base-4.8.2.0/docs/System-Environment.html#v:getArgs) и пропустите их - если вы хотите получить представление о том, что вы можете использовать Read/StateMonad (Transformers) и т. д. - то, что вы не можете сделать, конечно, - это использовать постоянные значения в вашем модуле - для чего-то большего вам нужно быть более конкретным, поскольку этот вопрос действительно к широкому – Carsten

+0

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

+0

@ Карстен Вы были правы, я редактировал свой пост, чтобы иметь более конкретный вопрос. – olp

ответ

4

поведение вашей программы зависит от аргументов, используемых в командной строке, просто нет способа скрыть этот факт - он должен появиться в типах компонентов вашей программы. Самый простой способ состоит в написании

data Options = {- ... -} 

doMyProgram :: Options -> IO() 
myModule'sConstantA :: Options -> A 
myModule'sConstantB :: Options -> B 

дает Options в качестве аргумента в любой операции или значение, которое зависит от него. Необычные проекты часто также определяют пользовательскую монаду M для программы, которая включает в себя экземпляр MonadReader Options M для уменьшения размера сигнатур типов.

+0

Спасибо за ваш ответ. Как вы говорите, нет способа сделать опцию глобальной поздней инициализированной константы? Проблема с Monad Reader заключается в том, что я не очень хорошо ее понимаю, но подпись еще длиннее, потому что она должна быть в возвращаемом типе. А как насчет расположения данных в памяти? (Я отредактировал мой пост, чтобы быть более точным) – olp

+0

@olp Извините, но даже после того, как вы задаете один и тот же вопрос разными словами, ответ будет таким же. –

0

Строго говоря, это не невозможно так много, как , вероятно, не должно быть сделано.

import System.Environment 
import System.IO.Unsafe 

firstArg :: String 
firstArg = head $ unsafePerformIO getArgs 
{-# NOINLINE firstArg #-} 

main = putStrLn firstArg 

Обратите внимание, сколько раз слово «небезопасно» появляется в этом шестистрочном фрагменте.

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

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