첫 번째 원리 중의 편지--JS로 해석
18638 단어 haskellfunctionaljavascriptbeginners
내가 편지의 개념을 이해하려고 시도할 때, 나는 보통 다음과 같은 해석 중의 하나를 얻는다.
나는 가능한 한 빨리 이 개념들을 해석해서 당신의 시간을 절약할 것입니다.
저는 일반적인 개념에서 시작하여 자바스크립트로 가능한 한 쉽게 접근할 수 있도록 프레젠테이션을 진행할 것입니다. 그러나 저는 여기서 Haskell을 소개할 것입니다. 왜냐하면 어떤 일들은 Haskell만 할 수 있기 때문에 이것은 당신의 이해에 매우 중요합니다.
목록은 편지입니다. 그 위에 비출 수 있습니다.
일화의 예로부터 시작하여 그곳에서 전개합시다.
많은 언어의 목록은 편지로 그것들 위에 비칠 수 있다.
const myList = [1,2,3,4,5]
const addTwo = (num) => num + 2
myList.map(addTwo) // [3,4,5,6,7]
맵은 구조에 함수를 적용하는 것입니다
위에서 본 것은 목록의 기본 매핑 함수입니다. 우리는
addTwo
함수를 목록의 모든 항목에 적용할 것입니다.그러나 매핑의 일반적인 정의는 다음과 같습니다.
Applying a function over *or* around some structure while keeping the structure intact.
목록에서 구조는 목록 자체다.우리는 함수addTwo
를 구조의 모든 항목, 즉 목록에 적용할 것이다. 목록의 존재를 모른다.알겠습니다.구조 매핑.구조가 무엇입니까?
네가
list
개의 예만 있을 때 먼저 구조의 개념을 이해하기는 좀 어렵다.그러나 이것이 편지의 중요한 통용 개념이 작용하는 곳이다.
'구조'를 하나의 상자로 상상하면 그 안에 어떤 가치가 있다.매핑할 때 함수를 상자 안의 잠재적 값에 적용하고 상자는 변하지 않습니다.
자바스크립트의 영역에 몸을 맡기는 것은 완벽하지 않지만 충분한 예가 될 것이다.
약속은 잠재적인 값을 포함하는 상자입니다. 약속 상자를 바꾸지 않고 함수를 적용할 수 있습니다.
let promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
// `then` is the equivalent of `map` in our example.
promise1.then(console.log);
console.log(promise1); // Will print out [object Promise]
여기서 무슨 일이 있었죠?우리는 미래 가치 평가의 상자라는 약속 대상이 있다.
then
방법은 함수를 프로미스 구조의 값에 응용하고 프로미스 대상 자체를 완전무결하게 유지한다.then
방법은 우리 세계의 map
에 해당한다.그래.알겠습니다.그런데 얇아 보이는데 무슨 소용이 있을까요?
나는 너를 지지한다.우리가 계속하기 전에, 너는 이 추상적인 가치를 설명하기 위해 더 많은 예를 필요로 한다.
이것이 바로 내가 고전 JS 영역을 떠나야 하는 곳이지만 너무 멀리 가지 마라.
Monad를 소개하겠습니다.걱정하지 마세요. 쪽지 부분은 우리의 설명과 무관합니다.가능한 부분일 뿐입니다.
아마도 리스트는 안전하게 존재할 수도 있고 존재하지 않을 수도 있는 값을 처리하는 방법일 것이다.
null
나 undefined
값이 아니라 우아하게 Nothing
사례를 처리하고functors 방법을 이용해야 할 수도 있습니다.기본적으로 Maybe는 옵션 값 상자입니다.만약 우리가 실현을 한다면 그것은 아마 이렇게 될 것이다.
let maybeName1 = Maybe("Snir")
let maybeName2 = Maybe(undefined)
console.log(maybeName1)
// [status: "Just", value: "Snir"]
console.log(maybeName2)
// [status: "Nothing"]
현재 이 Maybe
구조는 하나의 상자로 map
함수를 실현하여 하나의 편지가 되었다!잠재적map
구현을 살펴보겠습니다.// (This is not how `this` really works, assume `this` here is the
// currently referred Maybe object itself. Just for ease of read)
Maybe.map = (fun) => {
if (this.status === "Nothing") {
return;
}
return fun(this.value)
}
따라서 다음과 같이 인코딩할 수 있습니다.let maybeName1 = Maybe("Snir")
let maybeName2 = Maybe(undefined)
let maybes = [maybeName1, maybeName2]
maybes.map((maybeObj) => {
maybeObj.map((name) => console.log(`Hi ${name}!`)
}
// Will logs: "Hi Snir!"
보시다시피 Maybe는 값을 안전하게 저장하는 상자입니다. 맵을 사용하면 함수를 이 값에 적용할 수 있습니다. (이 문제를 해결할 수 있기 때문에 "null"값을 검사할 필요가 없습니다.)함수식 프로그래밍에서 이 상자들은 어디서나 볼 수 있다.그리고 저는 Haskell처럼 진화형 시스템을 가진 언어에서 그것들은 심지어 더욱 우아하다고 말할 수 있습니다.
더 많아!마지막 이상한 예는 함수다.
그래서 우리는 구조가 상자라는 것을 안다.목록은 많은 값을 포함하는 상자입니다. 아마도 안전 평가에서 선택할 수 있는 값일 것입니다.
함수도 상자야.코드 실행 데이터 상자입니다.
우리도 함수에 함수를 비출 수 있다!
이것이 바로 그것이 좀 이상하게 변한 부분이지만, 이것은 가장 중요한 예이다. 왜냐하면 그것은 당신이 무엇이 '구조' 인지에 대한 견해를 확장시켰기 때문이다.
유감스럽게도 JavaScript의 자연 영역을 떠나야 하는 부분이다. 왜냐하면 JS는 함수를 그 위에 편지를 실현하는 완벽한 상자로 삼지 않았기 때문이다.
여기서 중요한 것은 함수의 자연 부분 응용이다. 함수는Haskell, Scala, 그리고 많은 다른 함수 자연 언어에 존재한다.
예를 들어 Haskell에서 함수마다 항상 하나의 매개 변수만 얻을 수 있다.그러면 우리는 어떻게 한 논점이 아닌 논점을 전달합니까?Haskell은 첫 번째 매개 변수에서 만든 함수를 두 번째 매개 변수의 함수에 자동으로 적용합니다.
이것은 세계를 창조했다. 이 세계에서 일부 응용(또는 다른 이름으로curry) 함수는 언어의 첫 번째 기능이다.
이것 좀 봐.
-- This function takes 2 arguments: name, and address
printPerson name address = putStrLn (name ++ address)
-- Let's apply it with 2 arguments to get a print:
printPerson "Snir" " Tel Aviv"
-- This will print "Snir Tel Aviv"
-- We can also just partially apply, and store in another name:
printShani = printPerson "Shani"
-- This will not print anything yet. It just returns a partially applied function
printShani " New York"
-- This will print "Shani New York"
몇몇 자바스크립트 라이브러리는 Ramdajs와 그의 친구를 더욱 자연스럽게 할 수 있다.지금부터 나는 이 점을 자연스럽게 지지하는'허구적'JS로 시범을 보일 것이다. 그러면 너는 문법을 더욱 쉽게 따르고haskell과 함께 그것에 만족하는 사람들을 만족시킬 수 있을 것이다.
JS에서 함수의 일부 가상 매핑 구현을 살펴보겠습니다.
// NOTE: this is in an imaginary JS where partial application is natural. // This will not work in real life, it just for understanding the concept.
// And as with the example before, this is not really how `this` works.
// Just assume it refers to the context function, for readability.
Function.map = (fun) => {
this(fun)
}
이론적으로 이것은 우리로 하여금let add10 = (n) => n + 10
let multiply2 = (n) => n * 2
let addThenMultiply = add10.map(multiply2)
addThenMultiply(1) // Will result in 22
이것도 편지다.함수는 계산 정보를 저장하는 구조로 그 위의 매핑이 저장된 값을 바꾼다. 즉, 계산 정보를'10'에서'10을 더하고 2를 곱하기'까지 구조 자체를 바꾸지 않는 것이 함수의 개념이다.
만약 네가 알게 된다면, 너는 편지의 개념적 일반 개념을 얻었다고 안전하게 말할 수 있다.
깔끔함과 정확성을 위해haskell에도 같은 것이 있다.
-- The (->) is what represents functions in haskell.
-- This is an instance implementation of Functors to (->) - functions.
-- We implement the `fmap` here, which is just the `map` function.
instance Functor ((->) r) where
fmap f g = (\x -> f (g x))
-- Intentionally avoid point-free style, for easier read.
add10 n = n+10
multiply2 n = n*2
addThenMultiply = add10 `fmap` multiply2
addThenMultiply 1
예절!편지를 정식으로 정의합시다.
매우 적다너는 이미 이렇게 멀리 갔다.
우리는 편지의 형식으로 정의해서 그것을 끝낼 것이다.
편지는
map
함수를 실현해야 한다. 그러면 a
형식에서 b
형식까지 함수와 값이 A 형식인 편지를 가져와 b형식의 편지로 되돌아갈 수 있다.-- Formal haskell type definition
(a -> b) -> f a -> f b
이게 무슨 뜻이죠?우리 가볍게 시작합시다.우리는 목록
[1,2,3]
과 함수addOne = (n) => n + 1
가 하나 있다.그 다음에 목록은 편지입니다. 이것은
Number
의 값을 저장합니다.Th 함수는 Number
에서 Number
까지의 함수다.그래서 우리는 같은 종류의 편지 (숫자) 를 다시 받아야 한다.[1,2,3] -> [2,3,4]
이제 숫자에서 다른 유형의 함수가 있다고 가정해 봅시다.strNum => (n) => "num: " + n
그리고 규칙을 통해, 이것은 함수로 Number
에서 String
로 Number
의 편지 (목록) 를 String
의 편지로 변환할 것이다.[1,2,3] -> ["num: 1", "num: 2", "num: 3"]
.규칙.
편지가 예상대로 작동하도록 함수의 어떠한 일반적인 용법에서도 우리는 두 가지 기본 규칙을 준수해야 한다.
이것은 기본적으로 내가
map
에 no-op 함수를 전달한다면 편지는 변하지 않아야 한다는 것을 의미한다.기본적으로
map
기능을 제공하지 않은 상황에서 스스로 어떤 것도 바꾸어서는 안 된다.let noop = (n) => n
[1,2,3].map(noop)
// Must return `[1,2,3]` again.
이것은 조합 함수를 사용하는 매핑은 분리 함수를 사용하는 매핑과 같은 결과를 얻어야 한다는 것을 의미한다.
let addTwo = (n) => n + 2
let MultiplyTwo = (n) => n * 2
let addThenMultiply = (n) => MultiplyTwo(addTwo(n))
[1,2,3].map(addTwo).map(MultiplyTwo) // [6,8,10]
// Must be equivalent to the use of the composition morphism:
[1,2,3].map(addThenMultiply) // [6,8,10]
이렇게!붓을 대다
편지에 관해서는 아직 할 말이 많고, 더 많은 편지 변체가 포괄되어야 한다.
이것은 너로 하여금 이 개념에 대해 잘 이해하게 할 뿐만 아니라, 더욱 높은 화제로 통하는 간단한 경로가 될 것이다.
Reference
이 문제에 관하여(첫 번째 원리 중의 편지--JS로 해석), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/snird/functors-from-first-principle-37lh텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)