shopkeeper/korean_wiki_content_only_120125 huggingface dataset:
결과적으로 생성된 모나드는 리스트일 뿐만 아니라 함수가 적용될 때마다 자동으로 크기가 조정되고 자체적으로 응축되는 리스트이다.
는 이제 공식만으로도 파생될 수 있으며, codice_45 값을 모나드 함수의 파이프라인을 통해 공급하는 데 사용될 수 있다.
(xlist »= f) = join ∘ (map f) xlist
이 모나드 리스트의 한 가지 응용 프로그램은 비결정적 계산을 나타내는 것이다.
codice_45는 알고리즘의 모든 실행 경로에 대한 결과를 보유한 다음, 각 단계에서 자체적으로 응축하여 어떤 경로가 어떤 결과로 이어졌는지 "잊을" 수 있다 (때로는 결정적이고 완전한 알고리즘과 중요한 구별).
또 다른 이점은 검사를 모나드에 내장할 수 있다는 것이다. 특정 경로는 파이프라인의 함수를 다시 작성할 필요 없이 실패 지점에서 투명하게 가지치기될 수 있다.
codice_45가 빛을 발하는 두 번째 상황은 다가 함수를 구성하는 것이다.
예를 들어, 어떤 수의 번째 복소근은 개의 서로 다른 복소수를 생성해야 하지만, 그 결과에 대해 또 다른 번째 근이 취해지면 최종 개의 값은 번째 근의 출력과 동일해야 한다.
codice_45는 이 문제를 완전히 자동화하여 각 단계의 결과를 평탄하고 수학적으로 올바른 리스트로 압축한다.
모나드는 단순히 프로그램 논리를 구성하는 것을 넘어 흥미로운 기법들을 제공한다. 모나드는 유용한 문법적 기능의 토대를 마련할 수 있으며, 그 고수준 및 수학적 특성은 상당한 추상화를 가능하게 한다.
신택틱 슈거.
를 공개적으로 사용하는 것이 종종 의미가 있지만, 많은 프로그래머는 명령문과 유사한 구문(하스켈에서는 do-notation, OCaml에서는 perform-notation, F#에서는 계산 표현식, 스칼라에서는 for comprehension)을 선호한다. 이는 모나드 파이프라인을 코드 블록으로 위장하는 단순한 신택틱 슈거일 뿐이며, 컴파일러는 이러한 표현식을 기본 함수형 코드로 조용히 변환한다.
codice_21에서 codice_53 함수를 하스켈로 번역하면 이 기능을 확인할 수 있다. 하스켈에서 codice_53의 비모나드 버전은 다음과 같다.
Nothing -&gt; Nothing
Just x -&gt; case my of
Just y -&gt; Just (x + y)
모나드 하스켈에서 codice_55은 의 표준 이름이며, 람다 표현식은 명시적으로 처리해야 하지만, 이러한 기술적인 문제에도 불구하고 codice_21 모나드는 더 깔끔한 정의를 제공한다.
mx »= (\x -&gt;
my »= (\y -&gt;
하지만 do-표기법을 사용하면 이 과정을 더욱 직관적인 순서로 간결화할 수 있다.
x &lt;- mx
y &lt;- my
return (x + y)
두 번째 예는 codice_21가 완전히 다른 언어인 F#에서 어떻게 사용될 수 있는지를 보여준다.
계산 표현식을 사용하면, 정의되지 않은 피연산자나 0으로 나누기 연산에 대해 codice_28을 반환하는 "안전한 나누기" 함수를 다음과 같이 작성할 수 있다.
let readNum () =
let s = Console.ReadLine()
let succ,v = Int32.TryParse(s)
if (succ) then Some(v) else None
let secure_div =
maybe {
let! x = readNum()
let! y = readNum()
if (y = 0)
then None
else return (x / y)
빌드 시 컴파일러는 이 함수를 내부적으로 더 밀집된 호출 체인으로 "디슈거링"할 것이다.
maybe.Delay(fun () -&gt;
maybe.Bind(readNum(), fun x -&gt;
maybe.Bind(readNum(), fun y -&gt;
if (y=0) then None else maybe.Return(x / y))))
마지막 예시로, 일반 모나드 법칙 자체도 do-표기법으로 표현할 수 있다.
일반 인터페이스.
모든 모나드는 모나드 법칙을 만족하는 특정 구현이 필요하지만, 다른 구조와의 관계나 언어 내의 표준 관용구와 같은 다른 측면은 모든 모나드에서 공유된다.
결과적으로 언어 또는 라이브러리는 함수 원형, 서브타이핑 관계 및 기타 일반적인 사실을 포함하는 일반적인 codice_59 인터페이스를 제공할 수 있다.
개발을 시작하고 새로운 모나드가 슈퍼타입(함자와 같은)의 기능을 상속받도록 보장하는 것 외에도, 모나드의 설계를 인터페이스와 비교하여 확인하는 것은 품질 관리의 또 다른 계층을 추가한다.
모나드 코드는 종종 연산자를 현명하게 사용함으로써 더욱 단순화될 수 있다.
함수형은 특히 유용할 수 있는데, 이는 임시 모나드 함수뿐만 아니라 다양한 경우에 작동하기 때문이다. 모나드 함수가 미리 정의된 연산자와 유사하게 작동해야 하는 한, 을 사용하여 간단한 연산자를 즉시 모나드 연산자로 "올릴" 수 있다.
이 기법을 사용하면 codice_21 예제의 codice_53 정의를 다음으로 요약할 수 있다.
add(mx,my) = map (+)
이 과정은 codice_53를 codice_21뿐만 아니라 전체 codice_59 인터페이스에 대해 정의함으로써 한 단계 더 나아갈 수 있다.
이렇게 하면 구조 인터페이스와 일치하고 자체 을 구현하는 모든 새로운 모나드도 codice_53의 올림 버전을 즉시 상속받을 것이다.
함수에 필요한 유일한 변경 사항은 타입 시그니처를 일반화하는 것이다.
add : (Monad Number, Monad Number) → Monad Number
분석에 유용한 또 다른 모나드 연산자는 모나드 합성(여기서는 중위 codice_66로 표현됨)인데, 이는 모나드 함수를 보다 수학적인 스타일로 연결할 수 있도록 한다.
(f &gt;=&gt; g)(x) = f(x) »= g
이 연산자를 사용하면 모나드 법칙을 함수만으로 작성할 수 있으며, 결합성 및 항등원의 존재와의 대응을 강조한다.
(unit &gt;=&gt; g) ↔ g
(f &gt;=&gt; unit) ↔ f
(f &gt;=&gt; g) &gt;=&gt; h ↔ f &gt;=&gt; (g &gt;=&gt; h)
결과적으로, 위 내용은 하스켈의 "do" 블록의 의미를 보여준다.
_p &lt;- f(x)
_q &lt;- g(_p)
h(_q) ↔ ( f &gt;=&gt; g &gt;=&gt; h )(x)
항등 모나드.
가장 간단한 모나드는 항등 모나드인데, 이는 모나드 법칙을 만족하기 위해 일반 값과 함수에 주석을 달 뿐이다.
newtype Id T = T
unit(x) = x
(x »= f) = f(x)
codice_67는 재귀적인 모나드 트랜스포머의 기저 사례를 제공하는 것과 같이 유효한 사용 사례를 가지고 있다.
또한 명령형 스타일 블록 내에서 기본적인 변수 할당을 수행하는 데 사용될 수도 있다.
적절한 를 가진 모든 컬렉션은 이미 모노이드이지만, codice_45만이 잘 정의된 을 가지고 모나드의 자격을 갖춘 컬렉션은 아닌 것으로 밝혀졌다.
에 특수 속성을 부과하는 것만으로 codice_45를 다른 모나드 컬렉션으로 변형시킬 수도 있다.
IO 모나드 (하스켈).
앞서 언급했듯이, 순수 코드는 관리되지 않는 부작용을 가져서는 안 되지만, 프로그램이 효과를 명시적으로 설명하고 관리하는 것을 배제하지는 않는다.
이 아이디어는 하스켈의 IO 모나드의 핵심이다. 여기서 타입 codice_70의 객체는 세상에서 수행될 동작을 설명하는 것으로 볼 수 있으며, 선택적으로 타입 codice_3의 세상에 대한 정보를 제공한다. 세상에 대한 정보를 제공하지 않는 동작은 타입 codice_72를 가지며, 더미 값 codice_73를 "제공"한다.
프로그래머가 codice_74 값을 함수에 바인딩할 때, 함수는 이전 동작(사용자 입력, 파일 등)이 제공한 세상에 대한 정보를 기반으로 수행될 다음 동작을 계산한다. 가장 중요하게, IO 모나드의 값은 다른 IO 모나드를 계산하는 함수에만 바인딩될 수 있기 때문에, 바인드 함수는 동작의 결과를 수행할 다음 동작을 계산할 함수에만 제공될 수 있는 동작 시퀀스의 규율을 부과한다. 이는 수행할 필요가 없는 동작은 절대 수행되지 않으며, 수행해야 할 동작은 잘 정의된 시퀀스를 갖는다는 것을 의미한다.
예를 들어, 하스켈에는 파일 시스템에 대한 여러 함수가 있는데, 파일이 존재하는지 확인하는 함수와 파일을 삭제하는 함수가 있다.
두 함수의 타입 시그니처는 다음과 같다.
doesFileExist :: FilePath -&gt; IO Bool
removeFile :: FilePath -&gt; IO ()
첫 번째 함수는 주어진 파일이 실제로 존재하는지에 관심이 있으며, 그 결과 codice_74 모나드 내에서 불리언 값을 출력한다.
두 번째 함수는 파일 시스템에서 작동하는 것에만 관심이 있으므로 출력하는 codice_74 컨테이너는 비어 있다.
codice_74는 파일 I/O에만 국한되지 않는다. 사용자 I/O도 허용하며, 명령형 구문 설탕과 함께 일반적인 "Hello, World!" 프로그램을 모방할 수 있다.
name &lt;- getLine
putStrLn ("Nice to meet you, " ++ name ++ "!")
탈설탕화하면 다음과 같은 모나드 파이프라인으로 변환된다 (하스켈에서 codice_78는 모나드 효과만 중요하고 기본 결과는 버릴 수 있을 때의 변형일 뿐이다).
putStrLn "Hello, world!" »
putStrLn "What is your name, user?" »
getLine »= (\name -&gt;
Writer 모나드 (자바스크립트).
또 다른 일반적인 상황은 로그 파일을 유지하거나 프로그램의 진행 상황을 보고하는 것이다.
때로는 프로그래머가 나중에 프로파일링 또는 디버깅을 위해 더 구체적이고 기술적인 데이터를 로깅하기를 원할 수 있다.
Writer 모나드는 단계별로 누적되는 보조 출력을 생성함으로써 이러한 작업을 처리할 수 있다.
모나드 패턴이 주로 함수형 언어에만 국한되지 않는다는 것을 보여주기 위해, 이 예제에서는 자바스크립트로 codice_79 모나드를 구현한다.
먼저, 배열(중첩된 꼬리 포함)을 사용하면 codice_79 타입을 연결 리스트로 구성할 수 있다.
기본 출력 값은 배열의 0번 위치에 있고, 1번 위치는 보조 노트 체인을 암묵적으로 보유한다.
const writer = value =&gt; [value, []];
을 정의하는 것도 매우 간단하다.
const unit = value =&gt; [value, []];
만 있으면 디버깅 노트를 포함하는 codice_79 객체를 출력하는 간단한 함수를 정의할 수 있다.
const squared = x =&gt; [x * x, [`${x} was squared.`]];
const halved = x =&gt; [x / 2, [`${x} was halved.`]];
진정한 모나드는 여전히 를 필요로 하지만, codice_79의 경우 이는 단순히 함수의 출력을 모나드의 연결 리스트에 연결하는 것에 해당한다.
const bind = (writer, transform) =&gt; {
const [value, log] = writer;
const [result, updates] = transform(value);
return [result, log.concat(updates)];
이제 샘플 함수는 를 사용하여 연결될 수 있지만, 모나드 합성 버전(여기서는 codice_83라고 함)을 정의하면 이러한 함수를 더욱 간결하게 적용할 수 있다.
const pipelog = (writer, ...transforms) =&gt;
최종 결과는 계산 단계를 거치는 것과 나중에 감사하기 위해 로깅하는 것 사이의 깔끔한 관심사 분리이다.
// 결과 Writer 객체 = [8, ['4 was squared.', '16 was halved.']]
환경 모나드.
환경 모나드(리더 모나드 및 함수 모나드라고도 함)를 사용하면 계산이 공유 환경의 값에 따라 달라질 수 있다. 모나드 타입 생성자는 타입 를 함수 타입 에 매핑하며, 여기서 는 공유 환경의 타입이다. 모나드 함수는 다음과 같다.
다음 모나드 연산은 유용하다.
연산은 현재 컨텍스트를 검색하는 데 사용되며, 은 수정된 하위 컨텍스트에서 계산을 실행한다. 상태 모나드와 마찬가지로 환경 모나드의 계산은 단순히 환경 값을 제공하고 이를 모나드의 인스턴스에 적용하여 호출할 수 있다.
형식적으로, 환경 모나드의 값은 추가적인 익명 인수를 가진 함수와 동일하다. 및 는 SKI 조합자 계산법에서 각각 및 조합자와 동일하다.
상태 모나드.
상태 모나드는 프로그래머가 모든 타입의 상태 정보를 계산에 첨부할 수 있도록 한다. 모든 값 타입이 주어졌을 때, 상태 모나드의 해당 타입은 상태를 받아들인 다음 (타입 codice_84의) 새로운 상태와 함께 (타입 codice_85의) 반환 값을 출력하는 함수이다. 이는 환경 모나드와 유사하지만, 새로운 상태를 반환하므로 변경 가능한 환경을 모델링할 수 있다는 점이 다르다.
type State s t = s -&gt; (t, s)
이 모나드가 상태 정보의 타입인 타입 매개변수를 취한다는 점에 유의하라. 모나드 연산은 다음과 같이 정의된다.
-- "return"은 상태를 변경하지 않고 주어진 값을 생성한다.
return x = \s -&gt; (x, s)
-- "bind"는 m을 수정하여 결과를 f에 적용한다.
m »= f = \r -&gt; let (x, s) = m r in (f x) s
유용한 상태 연산은 다음과 같다.
get = \s -&gt; (s, s) -- 계산의 이 지점에서 상태를 검사한다.
put s = \_ -&gt; ((), s) -- 상태를 바꾼다.
modify f = \s -&gt; ((), f s) -- 상태를 업데이트한다.
다른 연산은 주어진 초기 상태에 상태 모나드를 적용한다.
runState :: State s a -&gt; s -&gt; (a, s)
runState t s = t s
상태 모나드의 do-블록은 상태 데이터를 검사하고 업데이트할 수 있는 일련의 연산이다.
비공식적으로, 상태 타입 의 상태 모나드는 반환 값의 타입 를 formula_3 타입의 함수로 매핑하며, 여기서 는 기본 상태이다. 및 함수는 다음과 같다.
범주론적 관점에서, 상태 모나드는 곱 함자와 지수 함자 사이의 수반에서 파생되며, 이는 정의상 모든 데카르트 닫힌 범주에 존재한다.
연속 모나드.
반환 타입 을 가진 연속 모나드는 타입 를 함수 타입 formula_5에 매핑한다. 이는 연속 전달 스타일을 모델링하는 데 사용된다. return 및 bind 함수는 다음과 같다.
Call-with-current-continuation 함수는 다음과 같이 정의된다.
프로그램 로깅.
다음 코드는 의사 코드이다. 두 함수 codice_86와 codice_87가 있다고 가정해 보자. 타입은 다음과 같다.
foo : int -&gt; int
bar : int -&gt; int
즉, 두 함수 모두 정수를 받아 다른 정수를 반환한다. 그러면 함수를 다음과 같이 연속적으로 적용할 수 있다.
foo (bar x)
결과는 codice_88에 codice_87를 적용한 결과에 codice_86를 적용한 결과이다.
그러나 프로그램을 디버깅 중이고 codice_86와 codice_87에 로깅 메시지를 추가하고 싶다고 가정해 보자.
그래서 타입을 다음과 같이 변경한다.
foo : int -&gt; int * string
bar : int -&gt; int * string
그래서 두 함수 모두 튜플을 반환하며, 적용 결과는 정수이고, 적용된 함수와 이전에 적용된 모든 함수에 대한 정보가 포함된 로깅 메시지는 문자열이다.
불행히도, 이는 codice_86와 codice_87를 더 이상 구성할 수 없다는 것을 의미한다. 입력 타입 codice_95가 출력 타입 codice_96과 호환되지 않기 때문이다. 그리고 각 함수의 타입을 codice_97으로 수정하여 구성 가능성을 다시 얻을 수 있지만, 이는 튜플에서 정수를 추출하기 위해 각 함수에 상용구 코드를 추가해야 하며, 이러한 함수의 수가 증가함에 따라 지루해질 것이다.
대신, 이 상용구를 추상화하는 도우미 함수를 정의해 보자.
bind : int * string -&gt; (int -&gt; int * string) -&gt; int * string
codice_16는 정수와 문자열 튜플을 받은 다음, 정수에서 정수와 문자열 튜플로 매핑하는 함수(예: codice_86)를 받는다. 그 출력은 입력 정수와 문자열 튜플 내의 정수에 입력 함수를 적용한 결과인 정수와 문자열 튜플이다.
이러한 방식으로, codice_16에서 튜플에서 정수를 추출하는 상용구 코드를 한 번만 작성하면 된다.
이제 우리는 구성 가능성을 어느 정도 회복했다. 예를 들어:
bind (bind (x,s) bar) foo
여기서 codice_101는 정수와 문자열 튜플이다.
이점을 더욱 명확히 하기 위해 codice_16의 별칭으로 중위 연산자를 정의해 보자.
(»=) : int * string -&gt; (int -&gt; int * string) -&gt; int * string
그래서 codice_103는 codice_104와 같다.
그러면 위 예시는 다음과 같이 된다.
((x,s) »= bar) »= foo
마지막으로, 빈 로깅 메시지를 생성할 때마다 codice_105를 작성하지 않도록 새 함수를 정의한다. 여기서 codice_106는 빈 문자열이다.
return : int -&gt; int * string
이는 위에서 설명한 튜플로 codice_88를 래핑한다.
그 결과는 로깅 메시지를 위한 파이프라인이다.
((return x) »= bar) »= foo
이를 통해 codice_87와 codice_86가 codice_88에 미치는 영향을 더 쉽게 로깅할 수 있다.
codice_96은 의사 코드화된 모나드 값을 나타낸다. codice_16와 codice_55은 같은 이름의 해당 함수와 유사하다.
사실, codice_96, codice_16, codice_55은 모나드를 형성한다.
가산 모나드.
가산 모나드는 추가적인 닫힌, 결합적인 이항 연산자 mplus와 아래의 항등 요소 mzero가 부여된 모나드이다.
codice_21 모나드는 로서 codice_24과 OR 연산자의 변형으로서 를 가진 가산 모나드로 간주될 수 있다.
codice_45 또한 가산 모나드로, 빈 리스트 codice_120는 역할을 하고 연결 연산자 codice_46는 역할을 한다.
직관적으로 는 기본 타입에서 값이 없는 모나드 래퍼를 나타내지만, 모나드 함수에 바인딩될 때마다 를 반환하는 의 흡수원 역할을 하므로 "1"이 아닌 "0"으로 간주된다.
이 속성은 양면적이며, 어떤 값이 모나드 영 함수에 바인딩될 때도 는 를 반환할 것이다.
범주론적 용어로, 가산 모나드는 (모든 모나드가 그렇듯이)를 가진 모나드 함수에 대한 모노이드로서 한 번, 그리고 를 통한 모나드 값에 대한 모노이드로서 다시 한 번 자격을 갖춘다.
자유 모나드.
때로는 모나드의 일반적인 윤곽이 유용할 수 있지만, 어떤 모나드가 다른 모나드보다 더 낫다고 추천할 만한 간단한 패턴이 없을 때가 있다.
이것이 자유 모나드가 등장하는 곳이다. 모나드 범주에서 자유 대상으로서, 모나드 법칙을 넘어서는 특정 제약 없이 모나드 구조를 나타낼 수 있다.
자유 모노이드가 평가 없이 요소를 연결하는 것처럼, 자유 모나드는 타입 시스템을 만족시키기 위해 마커와 함께 계산을 연결할 수 있지만, 그 자체로는 더 깊은 의미를 부여하지 않는다.
예를 들어, codice_122와 codice_24 마커를 통해 전적으로 작동함으로써 codice_21 모나드는 사실 자유 모나드이다.
반면에 codice_45 모나드는 리스트에 대한 추가적이고 구체적인 사실(와 같은)을 정의에 포함하기 때문에 자유 모나드가 아니다.
마지막 예시는 추상적인 자유 모나드이다.
data Free f a
= Pure a
| Free (f (Free f a))
unit :: a -&gt; Free f a
unit x = Pure x
bind :: Functor f =&gt; Free f a -&gt; (a -&gt; Free f b) -&gt; Free f b
bind (Pure x) f = f x
bind (Free x) f = Free (fmap (\y -&gt; bind y f) x)
그러나 자유 모나드는 이 예시처럼 연결 리스트에 국한되지 않으며, 트리와 같은 다른 구조를 중심으로 구축될 수도 있다.
자유 모나드를 의도적으로 사용하는 것이 처음에는 비실용적으로 보일 수 있지만, 그 형식적인 특성은 구문 문제에 특히 적합하다.
자유 모나드는 나중에 의미론을 남겨두고 구문과 타입을 추적하는 데 사용될 수 있으며, 그 결과 파서와 인터프리터에서 사용되었다.
다른 사람들은 이를 더 동적이고 운영적인 문제에도 적용했으며, 예를 들어 언어 내에서 반복자를 제공하는 데 사용했다.
코모나드.
추가 속성을 가진 모나드를 생성하는 것 외에도, 주어진 모나드에 대해 코모나드를 정의할 수 있다.
개념적으로, 모나드가 기본 값에서 구축된 계산을 나타낸다면, 코모나드는 값으로 다시 환원되는 감소로 볼 수 있다.
모나드 코드는 어떤 의미에서는 완전히 "압축 해제"될 수 없다. 값이 모나드 내부에 래핑되면, 어떤 부작용과 함께 그 안에 격리된 상태로 유지된다 (순수 함수형 프로그래밍에서는 좋은 점이다).
그러나 때로는 문제가 문맥 데이터를 소비하는 것에 더 가깝고, 코모나드는 이를 명시적으로 모델링할 수 있다.
기술적으로, 코모나드는 모나드의 범주론적 쌍대이며, 이는 느슨하게 말하면 타입 시그니처의 방향이 역전된 동일한 필수 구성 요소를 가질 것이라는 의미이다.
-중심 모나드 정의에서 시작하여, 코모나드는 다음으로 구성된다.
counit(wa) : W T → T
(wa =» f) : (W U, W U → T) → W T
및 은 또한 모나드 법칙의 쌍대도 만족해야 한다.
counit ∘ ( (wa =» f) → wb ) ↔ f(wa) → b
wa =» counit ↔ wa
wa ( (=» f(wx = wa)) → wb (=» g(wy = wb)) → wc ) ↔ ( wa (=» f(wx = wa)) → wb ) (=» g(wy = wb)) → wc
모나드와 마찬가지로 코모나드도 의 쌍대를 사용하여 함자에서 파생될 수 있다.
duplicate(wa) : W T → W (W T)
그러나 와 같은 연산은 역전되지만, 코모나드는 그에 작용하는 함수를 역전시키지 않으며, 결과적으로 코모나드는 여전히 을 가진 함자이지 공함자는 아니다.
, , 을 사용한 대체 정의도 자체 코모나드 법칙을 준수해야 한다.
((map duplicate) ∘ duplicate) wa ↔ (duplicate ∘ duplicate) wa ↔ wwwa
((map counit) ∘ duplicate) wa ↔ (counit ∘ duplicate) wa ↔ wa
((map map φ) ∘ duplicate) wa ↔ (duplicate ∘ (map φ)) wa ↔ wwb
모나드와 마찬가지로 두 형식은 자동으로 변환될 수 있다.
(map φ) wa ↔ wa =» (φ ∘ counit) wx
duplicate wa ↔ wa =» wx
wa =» f(wx) ↔ ((map f) ∘ duplicate) wa
간단한 예시는 곱 코모나드이며, 입력 값과 공유 환경 데이터를 기반으로 값을 출력한다.
사실, codice_127 코모나드는 codice_79 모나드의 쌍대이며 codice_129 모나드와 실질적으로 동일하다 (둘 다 아래에서 논의됨).
codice_127와 codice_129는 수용하는 함수 시그니처와 값 래핑 또는 언래핑을 통해 해당 함수를 보완하는 방식에서만 다르다.
덜 자명한 예는 스트림 코모나드인데, 이는 데이터 스트림을 나타내고 를 사용하여 들어오는 신호에 필터를 첨부하는 데 사용될 수 있다.
사실, 모나드만큼 인기가 있지는 않지만, 연구자들은 코모나드가 스트림 프로세싱 및 데이터플로 프로그래밍 모델링에 특히 유용하다는 것을 발견했다.
그러나 엄격한 정의 때문에 모나드와 코모나드 사이에서 객체를 단순히 앞뒤로 이동할 수는 없다.
더 높은 추상화로서 화살은 두 구조를 모두 포괄할 수 있지만, 모나드 및 코모나드 코드를 결합하는 더 세밀한 방법을 찾는 것은 활발한 연구 분야이다.
계산을 모델링하기 위한 대안:
관련 디자인 개념:
모나드의 일반화:
하스켈 위키 참고 자료:
튜토리얼:
흥미로운 사례:
Magisk는 존 우가 개발한 안드로이드 기기의 사용자 공간 시스템리스 루팅을 위한 자유-오픈 소스 소프트웨어이다. Magisk는 안드로이드 6.0 이상을 실행하는 기기를 지원한다.
Magisk는 사용자가 안드로이드 기기에 루팅 권한을 얻을 수 있게 해주는 자유-오픈 소스 소프트웨어이다. Magisk를 사용하면 다양한 수정 및 사용자 지정을 설치할 수 있어 안드로이드 애호가들에게 인기가 많다. 또한 Magisk는 내장된 Magisk Manager 앱과 함께 제공되어 사용자가 루팅 권한을 관리하고 다양한 모듈을 설치할 수 있게 한다.
Magisk는 모듈식 디자인을 가지고 있으며, 시스템리스 접근 방식을 위해 매직 마운트를 사용한다. 안드로이드 기기를 루팅하여 새로운 기능과 기능을 추가하는 안전하고 쉬운 방법을 제공한다.
사용자는 펌웨어 (init_boot.img 또는 boot.img)를 다운로드하고 Magisk를 사용하여 파일을 패치한다. 부트로더 잠금 해제 후, 패치된 파일은 패스트부트 또는 오딘 (삼성 기기용)을 사용하여 플래시된다. 이렇게 함으로써 Magisk는 안드로이드 기기의 부팅 과정에서 Init을 magiskinit으로 대체하여 루팅 권한을 얻는다.
Magisk는 존 우가 만든 작은 프로젝트로 시작되었다. 그러나 지금은 252명 이상의 기여자들로 성장했다. 버전 21에서는 안드로이드 11에 대한 지원이 추가되었다. 버전 22에서는 삼성 갤럭시 S21에 대한 지원이 추가되었다. 버전 26에서는 안드로이드 5 이하 버전에 대한 지원이 제거되었다. 원래 개발자인 존 우는 2021년 5월에 안드로이드 보안팀에서 일하기 시작했다.
레드부트(RedBoot, Red Hat Embedded Debug and Bootstrap firmware' 두문자어)는 eCos 실시간 운영체제 하드웨어 추상화 계층을 사용하여 임베디드 시스템을 위한 부트스트랩 펌웨어를 제공하는 오픈 소스 응용 소프트웨어이다.
레드부트는 임베디드 리눅스 및 eCos 응용 프로그램을 포함하여 직렬 또는 이더넷을 통해 임베디드 응용 프로그램을 다운로드하고 실행할 수 있도록 한다. GDB와 연동하여 임베디드 응용 프로그램의 개발 및 디버깅을 지원한다. 또한 직렬 또는 이더넷을 통해 접근할 수 있는 대화형 명령 줄 인터페이스를 제공하여 플래시 이미지, 이미지 다운로드, 레드부트 구성 등을 관리할 수 있도록 한다. 무인 또는 자동 시작을 위해 부트 스크립트를 플래시에 저장하여 플래시, 하드 디스크 또는 TFTP 서버에서 이미지를 로드할 수 있다.
EFI(Extensible Firmware Interface) 시스템 파티션 또는 ESP는 UEFI를 사용하는 컴퓨터에서 이용되는 데이터 저장 장치(일반적으로 하드 디스크 드라이브 또는 솔리드 스테이트 드라이브)의 파티션이다. 컴퓨터가 부팅될 때, UEFI 펌웨어는 ESP에 저장된 파일을 로드하여 운영체제와 다양한 유틸리티를 시작한다.
ESP에는 설치된 운영체제(부트로더, 부트 관리자, 커널 이미지)와 컴퓨터에 존재하는 하드웨어 장치에 대한 장치 드라이버 파일 및 부팅 시 펌웨어에서 사용되는 시스템 유틸리티 프로그램과 오류 로그와 같은 데이터 파일이 포함된다.
EFI 시스템 파티션은 UEFI 사양의 일부로 유지 관리되는 FAT 파일 시스템을 기반으로 하는 파일 시스템으로 포맷된다. 따라서 파일 시스템 사양은 원래 FAT 사양과 독립적이다. 실제 차이의 정도는 알려져 있지 않다. 애플은 인텔/X86-64 맥에서 사용해야 하는 별도의 도구를 유지 관리하고 있지만, 다른 시스템에서는 FAT 유틸리티를 잘 사용한다. GUID 파티션 테이블 (GPT) 방식에서 EFI 시스템 파티션의 전역 고유 식별자 (GUID)는 이고, 마스터 부트 레코드 (MBR) 파티션 테이블 방식에서의 ID는 이다. UEFI 펌웨어는 두 파티션 방식 모두를 지원해야 하므로, GPT 및 MBR로 파티션된 디스크 모두 EFI 시스템 파티션을 포함할 수 있다. 또한 엘 토리토 CD-ROM 및 DVD용 부팅 가능 형식도 지원된다.
UEFI는 파티션의 첫 번째 블록(섹터)을 호환성 코드를 위해 예약하여 레거시 부트 섹터를 효과적으로 생성함으로써 레거시 시스템과의 하위 호환성을 제공한다. 레거시 바이오스 기반 시스템에서는 파티션의 첫 번째 섹터가 메모리에 로드되고 실행이 이 코드로 전송된다. UEFI 펌웨어는 호환성 지원 모듈 (CSM)을 통해 레거시 바이오스 모드로 부팅할 때를 제외하고 MBR의 코드를 실행하지 않는다.
UEFI 사양은 MBR 파티션 테이블을 완전히 지원하도록 요구한다. 그러나 일부 UEFI 구현은 부팅 디스크에서 특정 유형의 파티션 테이블을 감지하면 즉시 바이오스 기반 CSM 부팅으로 전환하여, MBR로 파티션된 디스크에 포함된 EFI 시스템 파티션에서 UEFI 부팅이 수행되는 것을 효과적으로 방지한다.
UEFI 펌웨어는 USB 플래시 드라이브와 같은 이동식 저장 장치에서 부팅을 지원한다. 이를 위해 이동식 장치는 FAT12, FAT16 또는 FAT32 파일 시스템으로 포맷되며, 부트로더는 표준 ESP 파일 계층 구조에 따라 저장되거나 부트로더의 전체 경로를 시스템의 부팅 관리자에게 제공해야 한다. 반면에 고정 드라이브에서는 항상 FAT32가 예상된다.
GRUB 2, elilo 및 systemd-boot는 리눅스를 위한 일반적인, 완전한 독립형 UEFI 부트 관리자(일명 부트로더 관리자) 역할을 한다. UEFI 펌웨어에 의해 로드되면, 이들은 EFI 시스템 파티션에 국한되지 않고 지원하는 모든 장치, 파티션 및 파일 시스템에서 커널 이미지를 액세스하고 부팅할 수 있다.
EFI 시스템 파티션의 마운트 지점은 사용되는 부트로더에 따라 달라진다. GRUB 2 및 lilo/elilo와 같은 구형 부트로더는 기본적으로 codice_1를 사용한다. 반면, systemd-boot는 중첩된 codice_2 마운트와의 잠재적 복잡성 때문에 codice_1 대신 codice_4 또는 codice_5를 선호한다. 마운트 지점 경로에 관계없이, 리눅스가 부팅된 후에는 그 내용에 액세스할 수 있다.
리눅스 커널 EFI 부트 스텁.
EFI 부트 스텁은 일반적인 UEFI 부트로더를 사용하지 않고도 리눅스 커널 이미지를 부팅할 수 있게 한다. PE 포맷/COFF 실행 이미지로 가장하고 펌웨어에 UEFI 애플리케이션으로 나타남으로써, EFI 부트 스텁이 활성화된 리눅스 커널 이미지는 UEFI 펌웨어에 의해 직접 로드되고 실행될 수 있다. 이러한 커널 이미지는 바이오스 기반 부트로더에 의해서도 로드 및 실행될 수 있다. 따라서 EFI 부트 스텁은 단일 커널 이미지가 어떤 부팅 환경에서도 작동하도록 허용한다.
EFI 부트 스텁에 대한 리눅스 커널의 지원은 커널 구성 중 codice_6 (EFI 스텁 지원) 옵션을 켜서 활성화된다. 이 기능은 2012년 3월 18일에 출시된 리눅스 커널 메인라인 버전 3.3에 병합되었다.
Systemd-boot는 EFI 시스템 파티션만 액세스하여 구성된 EFI 이미지를 로드하고 실행하는 간단한 UEFI 부트 관리자이다. 구성 파일 조각, 커널 이미지 및 initrd 이미지는 EFI 시스템 파티션에 상주해야 한다. systemd-boot는 다른 파티션이나 파일 시스템의 파일에 액세스하는 것을 지원하지 않기 때문이다. 리눅스 커널은 UEFI 이미지로 직접 실행될 수 있도록 codice_7로 빌드되어야 한다.
인텔 기반 맥OS (X86 및 X86-64).
인텔 X86-64 프로세서 아키텍처를 사용하는 애플 맥 컴퓨터에서 EFI 시스템 파티션은 초기에는 비어 있으며 macOS 부팅에는 사용되지 않는다.
그러나 EFI 시스템 파티션은 펌웨어 업데이트를 위한 임시 영역과 부트 캠프 (소프트웨어)를 사용하여 윈도우 파티션으로 부팅하도록 구성된 맥 컴퓨터의 마이크로소프트 윈도우 부트로더에 사용된다.
iBoot라는 맞춤형 애플 UEFI 펌웨어는 부트로더를 찾고 로드하는 로직을 제어한다. iBoot는 원하는 부트로더를 선택하며 (잠재적으로 시작 키보드 조합이나 NVRAM을 통해 구성됨), 선택적으로 내부 macOS 설치 또는 codice_8라는 복구 시스템으로 폴백할 수 있다.
구형 비-UEFI 애플-인텔 아키텍처 기기에서는 EFI 시스템 파티션이 HFS+로 포맷되어야 했다. 타사 부트로더는 펌웨어에 의해 부팅 가능해지기 전에 특별한 ioctl 명령으로 "블레스"되어야 했으며, 이는 클래식 맥 OS의 시스템 폴더 블레싱의 유물이다. 그 외에는 인텔 기반 애플 컴퓨터가 실행할 수 있는 EFI 운영 체제나 부트로더 종류에는 제한이 없다.
iOS, iPadOS, 애플 실리콘 기반 macOS (AArch64).
아이폰, 아이패드, 2023년 이후의 모든 맥 컴퓨터와 같은 애플 실리콘 (AArch64)을 사용하는 장치는 EFI/UEFI 기능을 포함하지 않으므로 EFI 시스템 파티션을 사용하지 않는다.
윈도우의 UEFI 지원은 2008년 윈도우 비스타 SP1부터 시작되었다.
윈도우 부팅 관리자는 EFI 시스템 파티션의 하위 폴더에 위치한다.
윈도우 XP 64비트 에디션 및 이후 버전에서는 명령을 실행하여 EFI 시스템 파티션에 접근할 수 있다. 이는 지정된 드라이브에 EFI 시스템 파티션을 마운트한다. 아이테니엄 기반 컴퓨터에서만 사용 가능하다.
에이서 아이코니아 탭 A500(Acer Iconia Tab A500)은 에이서가 설계, 개발, 판매한 태블릿 컴퓨터이다. A500은 안드로이드 허니콤 운영체제로 출시되었으며, 현재는 아이스크림 샌드위치 4.0.3으로 업그레이드할 수 있다 (2012년 4월부터). 이 태블릿은 팩커드 벨 리버티 탭 G100과 거의 동일한 형태로도 판매되었다.
이 태블릿은 영상 통화를 위한 5MP 후면 카메라와 2MP 전면 카메라를 탑재했다. 1GHz 엔비디아 테그라 250 프로세서와 1024MB DDR2 RAM으로 구동된다. A500은 특정 국가에서 64GB 플래시로 판매되지만, 16GB 및 32GB 모델도 사용할 수 있다.
A500은 액세서리 키보드 도크에 하나만 제공되는 ASUS Eee Pad 트랜스포머와 달리 태블릿에 바로 풀 사이즈 USB 포트를 장착한 최초의 안드로이드 태블릿 중 하나였다. 안드로이드 허니콤 (3.2)의 최신 버전 이후 이 장치는 NTFS 및 리눅스 파티션을 포함하여 훨씬 더 다양한 USB 장치를 지원한다. 이전에는 호환되는 장치 수가 매우 제한적이었고, USB 마우스, 키보드 및 FAT32 형식 드라이브(NTFS 및 기타 파일 시스템은 루팅에 의존하는 앱을 통해 사용 가능했음)만 태블릿과 함께 사용할 수 있었다.
이 태블릿은 출시 당시 안드로이드 3.0과 함께 제공되었다. 안드로이드 3.1과 3.2는 나중에 무선 업데이트를 통해 제공되었고, 안드로이드 4.0.3 (아이스크림 샌드위치) 업데이트는 그 이후로 제공되었다 (2012년 4월).
루팅은 sc2k가 개발하여 xda-developers에 게시한 앱을 사용하여 가능했다. 안드로이드 버전 3.1까지 가능했으며, 그 이후에는 에이서가 취약점을 패치했지만, 이러한 취약한 안드로이드 버전 중 하나로 다운그레이드하면 3.2.1의 사전 루팅된 버전을 설치하기 전에 ClockworkMod 복구를 설치할 수 있다 또는 실제로 아이스크림 샌드위치를 설치할 수 있다.
에이서에서 유출된 안드로이드 4.0.3의 일부는 2012년 4월 출시 전 몇 달 동안 xda-developers에 게시되었다.
현재 유출된 정보를 기반으로 구축된 몇 가지 ROM이 있으며, 그중 다수는 에이서에서 새로운 릴리스가 나올 때마다 여러 번 업데이트되었다. 인기 있는 'Flexreaper' ROM과 같은 많은 ROM은 이제 실제 OTA 릴리스를 기반으로 한다.
2012년 4월 에이서는 아이스크림 샌드위치 4.0.3을 출시했는데, 일부 지역에서는 3월의 1.031.00 유출과 동일하다.
이 ICS 릴리스는 saurik의 'mempodroid' 익스플로잇을 사용하는 원래 유출 정보로 거슬러 올라가는 루팅 솔루션에 취약하다. sc2k의 이전 'itsmagic' 트릭은 업데이트된 부트로더에서는 더 이상 작동하지 않지만, 고유한 UID를 장치에서 얻어 보안 부트 키를 계산할 수 있다면 장치의 APX 모드를 사용하여 수정된 이미지를 설치할 수 있다. 패치된 부트로더를 설치하면 서명되지 않은 이미지를 로드할 수 있으므로, 패치된 부트로더와 ClockworkMod 복구를 조합하여 태블릿을 루팅하여 사용자 공간 익스플로잇의 필요성을 없앨 수 있다.
TegraOwners 포럼의 개발자들은 에이서의 승인이나 지지를 받지 않은 후속 안드로이드 릴리스의 커뮤니티 유지 및 개발 빌드를 제작했다. 이러한 릴리스에는 다음을 기반으로 한 빌드가 포함된다.
우분투 리눅스도 복구 이미지 대신 커널을 설치하여 에이서 아이코니아 A500에서 작동하도록 만들어졌다. 우분투 설치를 위한 루트 파일 시스템은 SD 카드에 저장해야 한다. 다른 출처에서도 chroot 및 VNC를 사용하여 리눅스 GUI를 통해 우분투 10.10을 실행할 수 있다고 명시하고 있다.
2019년에 안드로이드 Go가 출시되었다. 일부 유튜버들은 에이서 아이코니아 A500과 같은 태블릿을 듀얼 부팅하는 방법에 대한 비디오를 게시했다. 그들은 안드로이드 Go가 매우 가볍고 윈도우 10을 설치하기 위한 상당한 양의 공간을 확보한다고 말했다.
아쿠오스 폰 SH-06D(Aquos Phone SH-06D)는 샤프에서 제조한 안드로이드 스마트폰이다. 2012년 일본에서 현지 통신사 NTT 도코모를 통해 독점 출시된 이 장치는 듀얼 코어 프로세서와 720p 오토스테레오스코피 디스플레이를 특징으로 하며, NTT 도코모와 협력하여 개발된 새로운 모바일 TV 서비스를 지원하는 최초의 스마트폰으로 주목받았다.
2012년 6월, 다가오는 영화 를 기념하여 일본의 애니메이션 시리즈 신세기 에반게리온을 테마로 한 SH-06D 특별판이 출시되었다. 10,000대만 제작된 특별판은 재설계된 외관과 시리즈에 등장하는 MAGI 컴퓨터 시스템을 모델로 한 맞춤형 사용자 인터페이스를 특징으로 했다.
아쿠오스 SH-06D는 플라스틱 기반의 구조를 사용하며 방수 기능이 있다. 이 장치는 슬라이드형 안테나를 통합하고 있으며, 원세그 또는 NTT 도코모와 다른 일본 미디어 회사들의 합작 투자로 이루어진 구독 기반 서비스인 NotTV를 통해 모바일 텔레비전을 시청하는 데 사용할 수 있다. 이 서비스는 일본의 디지털 텔레비전 전환으로 인해 비어 있던 아날로그 지상파 TV에 사용되었던 무선 스펙트럼을 활용한다. SH-06D는 이 서비스의 두 가지 출시 기기 중 하나였으며, 다른 하나는 NEC 카시오에서 생산한 태블릿이었다.
이 장치는 4.5 인치 (110 mm) 720p 오토스테레오스코피 디스플레이, 1 GB RAM을 갖춘 듀얼 코어 1.2 GHz 텍사스 인스트루먼트 OMAP 시스템 온 칩, 그리고 마이크로SD를 통해 확장할 수 있는 8 GB의 내부 스토리지를 특징으로 한다. 이 장치는 운영 체제로 안드로이드 2.3 "진저브레드"를 탑재한다.
NERV 에디션.
2012년 3월, NTT 도코모는 당시 개봉을 앞둔 에반게리온 신극장판 영화 의 타이인으로 신세기 에반게리온 테마의 SH-06D 한정판인 SH-06D NERV를 공개했다. 표준 모델과 유사성을 유지하면서도, NERV 에디션은 다른 색상 구성과 NERV 조직 로고가 새겨진 새로운 후면 커버를 가진 약간 수정된 디자인을 특징으로 한다. 안드로이드 운영 체제도 스튜디오 카라와의 협력을 통해 디자인된 맞춤형 홈 화면과 위젯으로 맞춤화되었으며, 시리즈에 등장하는 MAGI 컴퓨터 시스템의 외관을 연상시키는 검정, 주황, 녹색 악센트가 있는 미래 지향적인 모습을 사용한다. 이 기기는 2012년 6월 29일 일본에서 출시되었으며, 단 10,000대만 생산되었다.
에이수스 이패드 트랜스포머 TF201(Asus Eee Pad Transformer TF201) 또는 에이수스 이패드 트랜스포머 프라임(Asus Eee Pad Transformer Prime)은 에이수스 트랜스포머 패드 시리즈의 2-in-1 분리형 태블릿이다. 이 제품은 쿼드 코어 프로세서를 탑재한 세계 최초의 안드로이드 태블릿 컴퓨터이며, 듀얼 코어 에이수스 이패드 트랜스포머의 후속작이다. 안드로이드 4.1을 실행한다. 트랜스포머 프라임은 2011년 11월 9일 에이수스에 의해 발표되었다. 2011년 12월 1일 대만에서 출시되었으며, 2011년 12월 19일 주 동안 캐나다와 미국에서 출시되었다.
이패드 트랜스포머 프라임은 1280x800 해상도의 10.1인치 IPS+ 멀티터치 터치스크린과 엔비디아 시스템 온 칩 (SoC)을 갖춘 태블릿 컴퓨터다. 802.11b/g/n 와이파이 모듈과 마이크로SD 카드 리더기가 있다.
옵션 도킹 키보드는 전체 QWERTY 자판 키, 터치패드, 하나의 USB 2.0 포트 및 하나의 시큐어 디지털 (SD) 카드 리더기, 그리고 전체 배터리 수명을 12시간에서 18시간으로 늘려주는 추가 배터리를 특징으로 한다. 사용하지 않을 때 태블릿을 보호하는 슬리브도 있다. 이는 와 유사하지만, 종이접기와 같은 방식으로 접힌다.
트랜스포머 프라임은 안드로이드 3.2 허니콤과 함께 출시되었다. 안드로이드 4.0.3 아이스크림 샌드위치 업데이트는 2012년 1월 11일 트랜스포머 프라임용으로 출시되었다. 이후 2012년 9월 27일 안드로이드 4.1.2 젤리빈으로 업데이트되었다.
이 태블릿은 에 최적화된 게임에서 그래픽 성능으로 주목받았으며, 립타이드 GP의 물은 "환상적"이라는 묘사를 이끌어냈다. 대조적으로, 쓰기 파일 전송 속도는 테스트된 태블릿 중 가장 느렸다. 2011년 12월에 리뷰 기기가 루팅되었다. 직접 커스텀 ROM을 설치하려던 사용자들은 2012년 1월 잠금 및 암호화된 부트로더를 발견하고 실망했다. 제조사는 즉시 부트로더 잠금 해제 도구 작업을 발표했지만, 이 도구를 사용하면 보증이 무효화되고 구글 비디오스와 같은 서비스를 통해 구매한 DRM 콘텐츠를 사용할 수 없게 된다. 안드로이드 폴리스 블로그의 오리지널 트랜스포머와의 비교에서 프라임이 선호되었다. 두 가지 "사소한" 단점은 스피커와 USB 포트 하나가 없어졌다는 점이었다.
하스브로 소송.
2011년 12월 22일, 장난감 제조업체 해즈브로는 상표권 침해로 에이수스를 상대로 소송을 제기했다. 해즈브로는 에이수스가 태블릿 판매를 위해 트랜스포머 프랜차이즈의 이름을 "트랜스포머 프라임"을 사용하고 있다고 주장하며 프라임의 이름을 변경할 것을 요구했다. 이름 변경에 실패할 경우, 그들은 에이수스가 프라임을 출시하는 것을 허용하지 않고 징벌적 손해 배상을 요구했다. 에이수스는 프라임의 출시가 영향을 받지 않을 것이라고 말했다. 그러나 2012년 5월 말 미국 판사는 "태블릿이 실제로 변형된다"는 점을 들어 하스브로의 판매 중단 요청을 기각했다.
GPS 및 Wi-Fi 문제.
2011년 12월 30일, 트랜스포머 프라임의 GPS 및 Wi-Fi 기능에 하드웨어 문제가 있다는 소식이 전해지기 시작했다. 사용자 포럼에서는 이 문제가 스핀 알루미늄 후면 패널이 GPS 신호를 효과적으로 차단하고, 포고 핀 커넥터 접촉 불량으로 추가적인 신호 손실을 일으키며, 적어도 일부 기기에서는 인쇄 회로 기판의 결함 때문이라고 주장했다. 전자의 문제는 에이수스 자체에서 해당 문제를 논의하는 답장으로 나중에 입증되었다. 에이수스는 "ASUS 트랜스포머 프라임은 금속 유니바디 디자인으로 제작되었으므로, 해당 소재가 위성에서 신호를 수신할 때 GPS 성능에 영향을 줄 수 있다"고 말하며 "이 제품은 전문적인 GPS 장치가 아니다"라고 덧붙였다. 가장 주목할 만한 점은, 그 후 미국 웹사이트의 트랜스포머 프라임 공식 사양 목록에서 GPS 기능을 제거했다는 것이다. 에이수스는 현재 트랜스포머 프라임을 구매한 모든 고객에게 2012년 7월 31일 (태평양 표준시)까지 "신호 수신을 개선하고 사용자 경험을 최적화하는 데 도움이 될 수 있는" 무료 GPS 동글을 제공한다.
3세대 모델.
CES 2012에서 제조사는 오리지널 제품 출시 한 달도 채 안 된 시점에 트랜스포머 프라임의 후속작인 에이수스 트랜스포머 패드 인피니티 (이전 명칭 TF700T)를 2012년 2분기 출시 예정으로 발표했다. 이 새 모델은 1.6 GHz로 클럭된 테그라 3 T33 프로세서 (프라임의 T30과 대조적으로)와 이전 모델의 해상도를 두 배 이상으로 높인 1,920×1,200픽셀 해상도의 업그레이드된 화면을 포함한다.
디스플레이는 178° 넓은 시야각으로 초고휘도 야외 가독성을 제공하는 슈퍼 IPS+ 패널로 업그레이드되었다. 신호 문제에 대한 응답으로, Wi-Fi, 블루투스 및 GPS 성능을 향상시키기 위해 상단 부분이 플라스틱으로 된 새로운 후면 패널 디자인을 포함한다. 전면 카메라는 1.2메가픽셀에서 2메가픽셀로 향상되었다. 12코어 GPU로 그래픽 성능이 향상되었다.
프리덤 251(Freedom 251)은 2016년 인도에서 프로모션 가격 에 처음 판매된 스마트폰이다. 링잉 벨스 프라이빗 리미티드(Ringing Bells Private Limited)에서 판매되었으며 세계에서 가장 저렴한 스마트폰으로 홍보되었다. 이 발표는 대중의 폭넓은 관심과 수백만 건의 주문을 불러일으켰으나, 곧 가격, 실현 가능성 및 배송 능력에 대한 회의론에 부딪혔다.
초기 기기들이 다른 회사의 브랜드가 변경된 전화기였으며 소수의 기기만 배송되었다는 사실이 밝혀지면서 사기 의혹이 제기되었다. 인도 인민당 소속의 국회의원인 키리트 소마이야는 이 전화기가 "가짜"라고 공개적으로 말하고 이 프로모션을 폰지 사기라고 설명했다. 그는 링잉 벨스 이사 모히트 고엘과 사장 아쇼크 차다에 대해 인도 형법 제420조 및 정보 기술법 위반으로 최초 정보 보고서 (FIR)가 등록되도록 불만을 제기했다. 그러나 알라하바드 고등법원은 수사 초기 단계에서 시기상조라는 이유로 FIR을 중단시켰다.
프로모션 가격은 2016년 2월 18일부터 21일까지 온라인 예약에 한해 한정된 시간 동안만 제공되었다. 웹사이트 트래픽이 너무 많아 첫날에 서버가 다운되었다. 회사는 정가가 약 가 될 것이라고 말한다.
회사는 2016년 6월까지 500만 대의 전화기를 판매할 계획이었다. 웹사이트가 다운될 당시, 251루피 가격으로 3만 건의 예약만 받아들인 상태였다. 예약이 마감될 무렵, 링잉 벨스는 에 해당하는 예약을 받았다고 주장했다.
링잉 벨스는 판매 첫날 프리덤 251을 사전 예약한 3만 명의 고객에게 환불을 제공하기로 약속했다. 회사는 환불이 2016년 3월 첫째 주에 고객들에게 도달했어야 한다고 밝혔다.
회사는 251루피 스마트폰에 대한 부정적인 추측 때문에 이러한 조치를 취하게 되었으며, 전화기를 예약한 고객은 이제 스마트폰이 배송된 후에만 결제할 것이라고 말했다.
인도 셀룰러 협회(ICA)는 스마트폰이 251루피라는 낮은 가격에 현실적으로 판매될 수 있는지에 대해 의문을 제기했으며, 라비 샨카르 프라사드 통신부 장관에게 개입을 요청했다. ICA에 따르면, 보조금 판매를 하더라도 판매 가격은 3,500루피(2016년 8월 31일 기준 52.28달러)보다 낮아서는 안 된다. ICA는 또한 정부 고위 인사들이 제품 출시 행사에 참석한 것에 대해 불만을 제기했다.
출시 당시 미디어에 시연되고 배포된 프로토타입은 브랜드가 변경된 Adcom 기기였으며, 이에 대해 Adcom은 링잉 벨스를 고소하겠다고 위협했다. 그러나 나중에 유통된 기기들은 원래 프로토타입과 완전히 달랐다.
힌두스탄 타임스에 글을 쓴 나라야난 마다반에 따르면, 251루피의 가격은 광고 파트너와의 거래를 통해서만 가능하다. 이러한 거래는 매우 많은 수의 핸드셋이 사용될 때만 가능할 것이다.
2016년 2월 20일, 정부 관계자들이 제품에 인도 표준국 인증이 없는 이유를 조사하기 위해 링잉 벨스 사무실을 급습했다.
일부 평론가들은 프리덤 251 판매가 사기라고 지적한다. 이 전화기는 원래 브랜드 라벨이 수정액으로 덮여 있는 중국 전화기처럼 보인다. 화면에 표시된 아이콘은 애플의 아이폰에서 복사된 것이다. 또한 많은 사람들이 전화기를 주문했지만 확인 이메일조차 받지 못했다는 보고도 있다. 인도 인민당 국회의원 키리트 소마이야는 링잉 벨스를 "폰지 가짜 회사 사기"라고 묘사했다. 그는 통신부, 인도 통신 규제 당국 및 기타 여러 부처에 회사를 조사할 것을 요청했다. 이러한 우려로 인해 결제 게이트웨이 제공업체인 PayUBiz는 물품이 배송될 때까지 링잉 벨스에 대한 결제를 보류하기로 결정했다.
통신부는 전화기에 대한 내부 평가를 실시한 후, 2,300~2,400루피(2016년 8월 31일 기준 34.36~35.85달러) 미만으로는 제공될 수 없다는 사실을 발견했다.
링잉 벨스는 또한 고객 서비스 제공업체인 Cyfuture로부터 사기 및 미지급 요금에 대한 고발을 받았다.
이후 조사 결과 회사가 고객뿐만 아니라 공급업체 및 직원까지 속인 것으로 드러났다. 프리덤 251 사기 금액은 약 에 달하는 것으로 추정된다.
고엘은 가자아바드에 본사를 둔 아얌 엔터프라이즈의 소유주가 링잉 벨스가 를 "사취했다"고 주장하며 FIR을 제기한 후, 앞서 언급된 사기 혐의로 인도 당국에 체포되었다.